E. Vladik and cards
time limit per test 

2 seconds

memory limit per test 

256 megabytes

input standard input

output 

standard output

Vladik was bored on his way home and decided to play the following game. He took n cards and put them in a row in front of himself. Every card has a positive integer number not exceeding 8 written on it. He decided to find the longest subsequence of cards which satisfies the following conditions:

  • the number of occurrences of each number from 1 to 8 in the subsequence doesn't differ by more then 1 from the number of occurrences of any other number. Formally, if there are ck cards with number k on them in the subsequence, than for all pairs of integers  the condition |ci - cj| ≤ 1 must hold.
  • if there is at least one card with number x on it in the subsequence, then all cards with number x in this subsequence must form a continuous segment in it (but not necessarily a continuous segment in the original sequence). For example, the subsequence [1, 1, 2, 2] satisfies this condition while the subsequence [1, 2, 2, 1] doesn't. Note that [1, 1, 2, 2] doesn't satisfy the first condition.

Please help Vladik to find the length of the longest subsequence that satisfies both conditions.

Input

The first line contains single integer n (1 ≤ n ≤ 1000) — the number of cards in Vladik's sequence.

The second line contains the sequence of n positive integers not exceeding 8 — the description of Vladik's sequence.

Output

Print single integer — the length of the longest subsequence of Vladik's sequence that satisfies both conditions.

Examples
input
3
1 1 1
output
1
input
8
8 7 6 5 4 3 2 1
output
8
input
24
1 8 1 2 8 2 3 8 3 4 8 4 5 8 5 6 8 6 7 8 7 8 8 8
output
17
Note

In the first sample all the numbers written on the cards are equal, so you can't take more than one card, otherwise you'll violate the first condition.

题解:

先简单翻译一下,给一个序列,求最长的满足下面条件的子序列:

第一,相同数字连续;第二,每种数字出现次数之差不超过1

我们来考虑,由于每种数字出现都是连续的,因此一种数字一旦出现过,就不能再出现第二次。

所以我们可以用二进制来压每种数字是否出现过。

那么,每种数字出现次数的限制怎么处理?

这个东西不好说,所以我们考虑,如果有一种选择,使得每种数字都出现了至少a次,

那么一定会有其他选择,使得每种数字都出现了至少a-1次,a-2次……1次。

因此,我们就可以二分了!二分枚举每种数字至少出现的次数len,那么每种数字要么出现len次,要么出现len+1次。

对于某个len,定义状态数组f[i][j]为前i位中,数字出现状态为j时出现len+1次的数的最大种数

设tmp=max{f[i][(1<<8)-1}},那么显然,ans=tmp*(len+1)+(8-tmp)*len

在选取新的数字时,新数字要么出现len次,要么出现len+1次,

那么状态方程也显而易见了(刷表),更新对应位置的f值即可

最后注意特判:如果二分得到len=0,那么ans=出现的数的种数

代码见下:

 #include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N=;
const int K=(<<)+;
int n,a[N],f[N][K],now[],bit[];//now数组用来记录转移位置
inline int max(int a,int b){return a>b?a:b;}
vector<int> loc[];
inline int judge(int len)
{
for(int i=;i<=;i++)now[i]=;
memset(f,0xaf,sizeof(f));
int inf=f[][];
f[][]=;
for(int i=;i<n;i++)
{
for(int j=;j<bit[];j++)
{
if(f[i][j]==inf)continue;
for(int k=;k<;k++)
{
if(j&bit[k])continue;
int pos=now[k+]+len-;
if(pos>=loc[k+].size())continue;
f[loc[k+][pos]][j|bit[k]]=max(f[loc[k+][pos]][j|bit[k]],f[i][j]);
pos++;
if(pos>=loc[k+].size())continue;
f[loc[k+][pos]][j|bit[k]]=max(f[loc[k+][pos]][j|bit[k]],f[i][j]+);
}
}
now[a[i]]++;
}
int ans=inf;
for(int i=;i<=n;i++)
ans=max(ans,f[i][bit[]-]);
if(ans==inf)return -;
return ans*(len+)+(-ans)*len;
}
int main()
{
bit[]=;for(int i=;i<=;i++)bit[i]=bit[i-]<<;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]),loc[a[i]].push_back(i);
int l=,r=n/+,ans=;
while(l<=r)
{
int mi=(l+r)>>;
if(judge(mi)!=-)ans=judge(mi),l=mi+;
else r=mi-;
}
if(ans==)
{
ans=;
for(int i=;i<=;i++)
if(!loc[i].empty())ans++;
}
printf("%d",ans);
}

codeforces743E

[codeforces743E]Vladik and cards的更多相关文章

  1. CodeForces743E. Vladik and cards 二分+状压dp

    这个题我们可以想象成_---___-----__的一个水柱它具有一遍优一遍行的性质因此可以用来二分最小值len,而每次二分后我们都要验根,we可以把这个水柱想成我们在每个数段里取前一段的那个数后一段有 ...

  2. 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 ...

  3. Codeforces Round #384 (Div. 2) E. Vladik and cards 状压dp

    E. Vladik and cards 题目链接 http://codeforces.com/contest/743/problem/E 题面 Vladik was bored on his way ...

  4. Vladik and cards

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

  5. CF384 div2 E. Vladik and cards

    题意 给你一个的排列,求一个满足条件的最长子序列 每种数字的差小于等于,并且每种数字之内是连续的 解法 首先单纯认为用肯定不行的 所以应该考虑二分答案(所求长度具有二分性) 再用dp判断是否可行,这个 ...

  6. Vladik and cards CodeForces - 743E (状压)

    大意: 给定序列, 求选出一个最长的子序列, 使得任选两个[1,8]的数字, 在子序列中的出现次数差不超过1, 且子序列中相同数字连续. 正解是状压dp, 先二分转为判断[1,8]出现次数>=x ...

  7. 【codeforces 743E】Vladik and cards

    [题目链接]:http://codeforces.com/problemset/problem/743/E [题意] 给你n个数字; 这些数字都是1到8范围内的整数; 然后让你从中选出一个最长的子列; ...

  8. Codeforces Round #384 (Div. 2) //复习状压... 罚时爆炸 BOOM _DONE

    不想欠题了..... 多打打CF才知道自己智商不足啊... A. Vladik and flights 给你一个01串  相同之间随便飞 没有费用 不同的飞需要费用为  abs i-j 真是题意杀啊, ...

  9. 「算法笔记」状压 DP

    一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...

随机推荐

  1. MySQL 安装 + Windows7

    Window版本 1.下载 http://dev.mysql.com/downloads/mysql/ 2.解压 如果想要让MySQL安装在指定目录,那么就将解压后的文件夹移动到指定目录,如:D:\m ...

  2. vcruntime140.dll 丢失64位系统

    1. 下载VC Redistributable for VS2015,网址https://www.microsoft.com/en-us/download/confirmation.aspx?id=4 ...

  3. 如何在存储过程的IN操作中传递字符串变量

    原始SQL如下: SELECT MONTH(OrderTime) AS datetype, SUM(DeliveryCount) AS decount, Region FROM (SELECT dbo ...

  4. 安装centos minimal 版本后的网络配置(linux)

    1.修改网卡配置文件 2.重启网络服务 3.测试网络

  5. 修改表的字段顺序(mysql)

    ALTER TABLE 表名 CHANGE 字段名 字段名 int not null default 1 AFTER 它前面的字段;

  6. Mybatis JPA-集成方案+源码

    2018-04-18 update 当前文章已过时,请访问代码仓库查看当前版本wiki. github https://github.com/cnsvili/mybatis-jpa gitee htt ...

  7. centos7 python2.7.5 升级python3.6.4

    (转)Linux Centos7 升级python2至python3 - 依然范儿特西的文章 - 知乎 https://zhuanlan.zhihu.com/p/33660059 1 查看python ...

  8. Linux 安装Redis<集群版>(使用Mac远程访问)

    阅读本文需要先阅读安装Redis<准备> 一 架构细节 所有的redis节点彼此互联(PING-PONG机制) 内部使用二进制协议优化传输速度和带宽 节点的fail是通过集群中超过半数的节 ...

  9. Python多重赋值

    可以将变量名视对象的一个链接 >>>foo1 = foo2 = 4.3 >>>foo1 is foo2 True >>>foo1 = 4.3 &g ...

  10. Python爬虫入门(5):URLError异常处理

    大家好,本节在这里主要说的是URLError还有HTTPError,以及对它们的一些处理. 1.URLError 首先解释下URLError可能产生的原因: 网络无连接,即本机无法上网 连接不到特定的 ...