【题目链接】:http://codeforces.com/problemset/problem/743/E

【题意】



给你n个数字;

这些数字都是1到8范围内的整数;

然后让你从中选出一个最长的子列;

要求这个子列中各个数字出现的次数的差的绝对值都不超过1;

且如果是相同的数字的话:

都是连在一起的(不会有分散的数字);

问你这个最长的序列的长度是多少;

【题解】



二分每个数字至少出现的次数x,(即最少出现x次,当然也可以是x+1次);

(单调性是显然的吧,因为如果每个数字出现5次是可行的话,那么3次肯定也是可以的,二分是正确的);

然后判断这样的序列存不存在;

可以一个数字一个数字的判断;

对于每个数字而言.

只有两种情况.在这个序列中,或者不在;

(想要加入到这个序列中,

则必须之前没有出现过,

因为题目有要求不能出现分散的块;

如果之前没有出现过;

则加入到这个序列中,

枚举它要出现x次,还是x+1次,

则可以写个lower_bound快速判断它之后的

第x个该数字(或是x+1)的位置,然后再从那个位置后一位开始,

继续选择,同时记录刚才那个数字已经加入到序列中;

(同时序列的长度递增x或是x+1)

当然也可以不选这个数字,则往后移动一位;

到了第n+1个位置的时候,看看是不是所有的8个数字都选了;

是的话则返回找到了一个序列,否则返回一个很小的值就好;

这些都用记忆化搜索写吧.

开个

f[i][s],表示当前扫描到第i个位置,当前选择的数字的状态为s;(二进制对应);

的最大序列长度;

bo[i][s]记录这个状态有没有找过.

i最大1000,s最大2^8=256

状态这么少,怎么样都不会超啦;

然后如果能找到x的序列,就尝试把x搞大一点,继续找;

然后x为0的情况没办法在做记搜的时候体现出来;

得自己一开始的时候预处理出ans



【Number Of WA】



0



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0),cin.tie(0) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1100;
const int MM = 1<<8;
const int INF = -0x3f3f3f3f; int n,a[N],mark,ans,f[N][MM+10];
bool bo[N][MM+10];
vector <int> v[10]; int dfs(int i,int s,int x)
{
if (bo[i][s]) return f[i][s];
bo[i][s] = true;
if (i>n)
{
if (s==MM-1)
{
return f[i][s] = 0;
}
else
return f[i][s] = INF;
}
int ret = INF;
if (!((s>>(a[i]-1))&1))
{
int pos = lower_bound(v[a[i]].begin(),v[a[i]].end(),i)-v[a[i]].begin();
if (pos+x-1<int(v[a[i]].size()))
{
ret = max(ret,x+dfs(v[a[i]][pos+x-1]+1,s|(1<<(a[i]-1)),x));
}
if (pos+x<int(v[a[i]].size()))
{
ret = max(ret,x+1+dfs(v[a[i]][pos+x]+1,s|(1<<(a[i]-1)),x));
}
}
f[i][s] = max(ret,dfs(i+1,s,x));
return f[i][s];
} bool ok(int x)
{
ms(f,INF);
ms(bo,0);
int ret = INF;
ret = max(ret,dfs(1,0,x));
ans = max(ans,ret);
if (ret>=0)
return 1;
else
return 0;
} int main()
{
//Open();
Close();//scanf,puts,printf not use
//init??????
cin >> n;
rep1(i,1,n)
{
cin >> a[i];
if(!((mark>>a[i])&1))
{
mark|=(1<<a[i]);
ans++;
}
v[a[i]].pb(i);
}
int l = 1,r = n/8;
while (l<=r)
{
int mid = (l+r)>>1;
if (ok(mid))
l = mid+1;
else
r = mid-1;
}
cout << ans << endl;
return 0;
}

【codeforces 743E】Vladik and cards的更多相关文章

  1. 【35.02%】【codeforces 734A】Vladik and flights

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  2. 【codeforces 546C】Soldier and Cards

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. 【44.64%】【codeforces 743C】Vladik and fractions

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. 【CodeForces - 546C】Soldier and Cards (vector或队列)

    Soldier and Cards 老样子,直接上国语吧  Descriptions: 两个人打牌,从自己的手牌中抽出最上面的一张比较大小,大的一方可以拿对方的手牌以及自己打掉的手牌重新作为自己的牌, ...

  5. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  6. 【codeforces 777B】Game of Credit Cards

    [题目链接]:http://codeforces.com/contest/777/problem/B [题意] 等价题意: 两个人都有n个数字, 然后两个人的数字进行比较; 数字小的那个人得到一个嘲讽 ...

  7. 【27.85%】【codeforces 743D】Chloe and pleasant prizes

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. 【47.40%】【codeforces 743B】Chloe and the sequence

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  9. 【codeforces 707E】Garlands

    [题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...

随机推荐

  1. 【hiho一下 第十一周】树中的最长路

    [题目链接]:http://hihocoder.com/problemset/problem/1050 [题意] [题解] 有一个经典的求树的直径的方法; 首先; 树的直径的两端的端点必然都在树的叶子 ...

  2. mysql在windows下主从同步配置

    mysql主从同步:   1.为什么要主从同步? 在Web应用系统中,数据库性能是导致系统性能瓶颈最主要的原因之一.尤其是在大规模系统中,数据库集群已经成为必备的配置之一.集群的好处主要有:查询负载. ...

  3. 如何打开WCF测试客户端

  4. poi读取合并单元格

    poi读取合并单元格 学习了:http://blog.csdn.net/ycb1689/article/details/9764191 进行了列合并单元格的修正:原来是我自己找错了地方: import ...

  5. hdu3966_树链剖分

    近期在强化知识点深度.发现树链剖分不是非常会写了. 回想一下改动操作: 若两个点在同一条链上,则直接改动这段区间. 若不在同一条链上,改动深度较大的点到其链顶端的区间,同一时候将这个点变为他所在链顶端 ...

  6. awesome-free-software

    Free software is distributed under terms that allow users to run the program for any purpose, study ...

  7. 0x27 A*

    终于完全了解A*到底是什么玩意儿了 对于当前的决策,选取当前花费+预估花费最小来拓展. 因为假如预估出现失误,那么很可能就会延伸到一个错误的决策点,而这个决策点偏偏就是ed,而由于预估失误,其他点的当 ...

  8. kentico7中设置网站的主页

    打开SiteManager,选择Settings,然后左上角选择具体的网站,Content,Web Site Content,Default alias path

  9. 18.QT消息链筛选机制以及组合键

    mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> 5 #include <Q ...

  10. 19. Remove Nth Node From End of List[M]删除链表的倒数第N个节点

    题目 Given a linked list, remove the n-th node from the end of list and return its head. *Example: Giv ...