题目大意

给定一个序列an,序列中只有1~8的8个整数,让你选出一个子序列,满足下列两个要求

1.不同整数出现的次数相差小于等于1

2.子序列中整数分布是连续的,即子序列的整数必须是1,1,1....1,2,2,2.....2,2.......连续分布

做法:

那么我们可以二分不同整数出现的次数,假如说二分出现次数是L,那么可以证明有a个整数出现次数是L,有(8-a)个整数出现次数是L-1(同时不难证明L+1比L更优)

这样每个整数只有两种状态,要么选L个,要么选L-1个。

压缩决策s,s的第i位表示是否对整数i做出了决策

再用容器把每一个不同整数出现的序列记录下来,这样就可以进行dp了

设dp[i][s]表示从原序列扫到前i个数,已经做出了s的决策,出现L次的不同整数个数最大是多少

枚举对第k个整数做决策,dp[i][s]就可以转移到另外两个状态

dp[next(k, L-1)][s|(1<<k)] = max(itself, dp[i][s]);

dp[next(k, L)][s|(1<<k)] = max(itself, dp[i][s]+1);

其中next(k, L)是指从i开始,往后的第L个k的整数位置

然后取dp[1~n][(1<<8)-1]中的最大值,返回答案即可

另外如果最大值小于等于0(注意等于!!),说明不存在解,返回0即可。

需要注意的是,当l = 2都不可行的时候需要特判处理。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = ;
const int inf = 1e9;
int dp[maxn][<<], a[maxn], cur[maxn], n;
vector <int> in[];
int can(int L)
{
for(int i = ; i <= ; i++) cur[i] = ;
memset(dp, , sizeof(dp));
dp[][] = ;
for(int i = ; i <= n; i++)
{
for(int s = ; s < (<<); s++)
{
if(dp[i][s] < ) continue;
for(int k = ; k <= ; k++)
{
if(s & (<<(k-))) continue;
if(in[k].size() - cur[k] < L-) continue;
dp[in[k][cur[k] + L - ]][s|(<<(k-))] = max(dp[in[k][cur[k] + L - ]][s|(<<(k-))], dp[i][s]);
if(in[k].size() - cur[k] < L) continue;
dp[in[k][cur[k] + L - ]][s|(<<(k-))] = max(dp[in[k][cur[k] + L - ]][s|(<<(k-))], dp[i][s]+);
}
}
cur[a[i]]++;
}
int ans = -inf;
for(int i = ; i <= n ; i++) ans = max(ans, dp[i][(<<) - ]);
if(ans <= ) return ;
return ans * L + ( - ans)*(L-);
} int main()
{
//freopen("a.txt", "r", stdin);
cin>>n;
for(int i = ; i <= n; i++) cin>>a[i];
for(int i = ; i <= n; i++) in[a[i]].push_back(i);
int l = , r = n, ans = -inf;
while(l < r)
{
int mid = (l+r)>>;
if(can(mid)) l = mid+;
else r = mid;
}
if(can() == )
{
ans = ;
for(int i = ; i <= ; i++) if(in[i].size() > ) ans++;
cout<<ans<<endl;
}
else
{
ans = max(can(l), can(l-));
cout<<ans<<endl;
}
}

Codeforces Round #384 (Div. 2) 734E(二分答案+状态压缩DP)的更多相关文章

  1. Codeforces Round #262 (Div. 2)C(二分答案,延迟标记)

    这是最大化最小值的一类问题,这类问题通常用二分法枚举答案就行了. 二分答案时,先确定答案肯定在哪个区间内.然后二分判断,关键在于怎么判断每次枚举的这个答案行不行. 我是用a[i]数组表示初始时花的高度 ...

  2. Codeforces Round #389 (Div. 2) 752E(二分答案)

    题目大意 可以理解成有n个木板,可以选取木板将其劈成2半(如果长度是奇数,就切成x和x+1),切完之后还可以再切 然后你要把这n个木板切成更多的木板,然后从中选择k个,使得这k个木板的最小长度尽量大 ...

  3. Codeforces Round #384 (Div. 2) 734E Vladik and cards

    E. Vladik and cards time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  4. Codeforces Round #404 (Div. 2) C 二分查找

    Codeforces Round #404 (Div. 2) 题意:对于 n and m (1 ≤ n, m ≤ 10^18)  找到 1) [n<= m] cout<<n; 2) ...

  5. Codeforces Round #384(div 2)

    A 题意:有n个机场处于一直线上,可两两到达,每个机场只可能属于两家公司中的一家(用0,1表示),现在要从a机场到b机场,可任意次转机.若机场i与机场j从属同一公司,则费用为0,否则费用为1.问最小费 ...

  6. Codeforces Round #267 (Div. 2) C. George and Job(DP)补题

    Codeforces Round #267 (Div. 2) C. George and Job题目链接请点击~ The new ITone 6 has been released recently ...

  7. Codeforces Round #538 (Div. 2) D. Flood Fill 【区间dp || LPS (最长回文序列)】

    任意门:http://codeforces.com/contest/1114/problem/D D. Flood Fill time limit per test 2 seconds memory ...

  8. Codeforces Round #324 (Div. 2) C (二分)

    题目链接:http://codeforces.com/contest/734/problem/C 题意: 玩一个游戏,一开始升一级需要t秒时间,现在有a, b两种魔法,两种魔法分别有m1, m2种效果 ...

  9. Codeforces Round #377 (Div. 2)D(二分)

    题目链接:http://codeforces.com/contest/732/problem/D 题意: 在m天中要考k个课程, 数组a中有m个元素,表示第a[i]表示第i天可以进行哪门考试,若a[i ...

随机推荐

  1. Oracle 的jdbc方法

    package com.swift.jdbc_oracle; import java.sql.CallableStatement; import java.sql.Connection; import ...

  2. ABAP调用WebService时日期类型问题

    在使用ABAP调用WebService时, 提示CX_SY_CONVERSION_NO_DATE_TIME,意思是日期格式不能转化. 究其原因是ABAP里没有相应的数据类型与WebService描述里 ...

  3. mysql指定id默认第一

    有个需求 家庭创建人要默认排第一,刚开始用加入家庭的时间排序可以  好简单, 后来加了一个需求 家庭创建人可以转移,结果按时间排序就不行了,又不想去写循环重新排序 就各种百度, 等于就是指定ID排最后 ...

  4. python逻辑运算(not,and,or)总结

    逻辑运算 1.在没有()的情况下not优先级高于and,and优先级高于or,即优先级关系为()>not>and>or,同一优先级从左往右计算 总结:a or b : 如果a = 0 ...

  5. H5拍照、选择图片上传组件核心

    背景 前段时间项目重构,改成SSR的项目,但之前用的图片选择上传组件不支持SSR(server-side-render).遂进行了调研,发现很多的工具.但有的太大,有的使用麻烦,有的不满足使用需求.决 ...

  6. python 一些基础知识

    Python 注释的原理: 原理:根据对象的引用计数器,对象创建会给对象一个引用计数器属性.如果该属性的值为0,那么该对象会被释放.创建一个字符串对象,但是没有任何引用,计数器为0. Python小整 ...

  7. 关于Mysql唯一索引的操作方法(添加删除)

    首先我们查看一下News数据表的索引信息      使用命令 show index from ‘数据表名称’; 目前数据表中仅有一个主键索引 继续,我们给news表添加两个唯一索引(两种方法) 方法一 ...

  8. windows下使用curl.exe模拟ajax请求

    curl 是一般linux发行版中都带有的小工具,利用这个工具可以很方便的下载文件,我一般使用这个工具来查看某个页面相应的HTTP头信息,在Windows系统中我们也一样可以使用这个工具,如果不需要支 ...

  9. 实例讲解如何利用jQuery设置图片居中放大或者缩小

    大家有没有见过其他网站的图片只要鼠标放上去就能放大,移出去的时候就能缩小,而且一直保持居中显示!其实jQuery提供一个animate函数可以使图片放大和缩小,只要改变图片的长和高就OK啦!但是ani ...

  10. python+scrapy环境搭建步骤描述

    Python3(3.5.4)搭建爬虫系统步骤描述: 1.下载python安装包,路径:https://www.python.org/downloads/windows/  选择3.5.4版本64位的安 ...