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 ...
随机推荐
- JDK 动态代理 讨债实例
现弄一个讨债接口 package cn.itcast.g_dongtaidaili; public interface Taozhai { void taozhai(); } 再弄一个讨债实现类 pa ...
- 理解 Gulp 和 Webpack(转)
Gulp 和 webpack 之间的关系是十分暧昧的,却也经常被人误解,以为它俩是竞争关系,其实不然. Gulp 是一个任务管理工具,让简单的任务更清晰,让复杂的任务易于掌控:而 webpack 的理 ...
- DNS的主从,转发与负载功能
接着原来<DNS原理与应用>的文章,本章内容主要通过实现DNS的主从,转发,及基于域名解析不同的ip实现后端服务负载均衡的效果.最后再实现DNS的高级功能:类似CDN原理实现基于IP实现区 ...
- datatables 给字段设置默认值,屏蔽没有字段的错误
我们返回的数据不能保证都是正常的,可能包含 null ,显然这个对于最终用户来说是不友好的,那么我们可以这么处理 先有如下数据格式: //示例数据 { data:[ {"id":1 ...
- Mysql: pt-table-checksum 和 pt-table-sync 检查主从一致性,实验过程
一.安装 percona 包 1.安装仓库的包 https://www.percona.com/doc/percona-repo-config/yum-repo.html sudo yum insta ...
- Ansible工作架构和原理
特性 模块块化调用持定的模块,完成持定任务 有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块 支持自定义模块 基于Python语法头现 部署简单,基于python和SSH(默认已 ...
- Struts2之类范围拦截器和方法拦截器
1.Struts2拦截器的体系结构 Struts2拦截器最大的特点是其透明性,即用户感觉不到它的存在,但我们在使用Struts2框架时,拦截器时时刻刻都在帮助我们处理很多事情. 包括: 文件上传 表单 ...
- yii rbac
一.简介 什么是rbac ? rbac是就是基于角色的访问控制. yii提供一套基础的底层接口,我们知道,rbac经历好几个阶段,从rbac0到rbac3,从基础的用户.角色.权限,到动态的rbac处 ...
- 千锋教育Vue组件--vue基础的方法
课程地址: https://ke.qq.com/course/251029#term_id=100295989 <!DOCTYPE html> <html> <head& ...
- #Python编程从入门到实践#第三章笔记
列表简介 1.什么是列表 列表:由一系列按也顶顺序排列的元素组成.元素之间可以没有任何关系. 列表:用方括号[]表示,并用逗号分隔其中元素.名称一般为复数 2.访问元素 (1)列表是有序集合 ...