Codeforces Round #384 (Div. 2) 734E(二分答案+状态压缩DP)
题目大意
给定一个序列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)的更多相关文章
- Codeforces Round #262 (Div. 2)C(二分答案,延迟标记)
这是最大化最小值的一类问题,这类问题通常用二分法枚举答案就行了. 二分答案时,先确定答案肯定在哪个区间内.然后二分判断,关键在于怎么判断每次枚举的这个答案行不行. 我是用a[i]数组表示初始时花的高度 ...
- Codeforces Round #389 (Div. 2) 752E(二分答案)
题目大意 可以理解成有n个木板,可以选取木板将其劈成2半(如果长度是奇数,就切成x和x+1),切完之后还可以再切 然后你要把这n个木板切成更多的木板,然后从中选择k个,使得这k个木板的最小长度尽量大 ...
- 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 ...
- 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) ...
- Codeforces Round #384(div 2)
A 题意:有n个机场处于一直线上,可两两到达,每个机场只可能属于两家公司中的一家(用0,1表示),现在要从a机场到b机场,可任意次转机.若机场i与机场j从属同一公司,则费用为0,否则费用为1.问最小费 ...
- 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 ...
- 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 ...
- Codeforces Round #324 (Div. 2) C (二分)
题目链接:http://codeforces.com/contest/734/problem/C 题意: 玩一个游戏,一开始升一级需要t秒时间,现在有a, b两种魔法,两种魔法分别有m1, m2种效果 ...
- Codeforces Round #377 (Div. 2)D(二分)
题目链接:http://codeforces.com/contest/732/problem/D 题意: 在m天中要考k个课程, 数组a中有m个元素,表示第a[i]表示第i天可以进行哪门考试,若a[i ...
随机推荐
- 微信 php 获取token 第二次失败解决办法
第一次成功了,第二次总是失败,很简单,session问题 clearstatcache(); $_SESSION = ''; $_COOKIE = ''; //获得参数 signature nonce ...
- linux特殊权限位suid
特殊权限位基本说明(了解): linux系统基本权限位为9位权限,但还有额外3位权限位,共12位权限: suid s(x) S 4 用户对应的权限位(用户对应的3位 ...
- Java OOP——第五章 异常
1. 尝试通过if-else来解决异常问题: Eg: public class Test2 { public static void main(String[] args) { ...
- scrapy--BeautifulSoup
BeautifulSoup官方文档:https://beautifulsoup.readthedocs.io/zh_CN/latest/#id8 太繁琐的,精简了一些自己用的到的. 1.index.h ...
- 谈一谈你对js线程的理解
js线程:javascript是单线程的,所有任务都需要排队,这些任务分为同步任务和异步任务,单线程上有一个主线程任务.同步任务必须再主线程上排队进行,而异步任务(类似于点击事件)必须在主线程上的任务 ...
- 平衡二叉查找树 AVL 的实现
不同结构的二叉查找树,查找效率有很大的不同(单支树结构的查找效率退化成了顺序查找).如何解决这个问题呢?关键在于如何最大限度的减小树的深度.正是基于这个想法,平衡二叉树出现了. 平衡二叉树的定义 (A ...
- java基础不牢固容易踩的坑
java基础不牢固容易踩的坑 经过一年java后端代码以及对jdk源码阅读之后的总结,对java中一些基础中的容易忽略的东西写下来,给偏爱技术热爱开源的Coder们分享一下,避免在写代码中误入雷区. ...
- 【转载】Callable、FutureTask中阻塞超时返回的坑点
本文转载自:http://www.cnblogs.com/starcrm/p/5010863.html 案例1: package com.net.thread.future; import java. ...
- Flask错误收集 【转】
感谢大佬 ---> 原文链接 一.pydev debugger: process XXXXX is connecting 这个错误网上找了很多资料都无法解决,尝试过多种方法后,对我来说,下面这个 ...
- 2018"百度之星"程序设计大赛 - 资格赛 - 题集
1001 $ 1 \leq m \leq 10 $ 像是状压的复杂度. 于是我们(用二进制)枚举留下的问题集合 然后把这个集合和问卷们的答案集合 $ & $ 一下 就可以只留下被选中的问题的答 ...