Codeforces Round #384 (Div. 2) E
给出n个数字 1-8之间 要求选出来一个子序列 使里面1-8的数字个数 极差<=1 并且相同数字必须相邻(112 可以但是121不行)求这个子序列的最长长度
一道状压dp 看不懂别人的dp思想..自己造了一个出来..
首先枚举t 意义是 当前选取子序列 每个数字最少是多少 那么这个子序列中的数字个数为t t+1
dp[i][j]当前在i位 选取数字的情况压缩成j
枚举没选过的数字 用前缀和进行二分查找
从第i位开始 求出res使在满足i-res这个区间有t或者t+1的某数字 进行转移 更新dp[res][j|x]
当t为0的时候和t>0的时候 一个是 某种数字不选也可以 一个是每种数字都会被选择 所以分开来讨论
前者就是统计出现过的数字的种数
后者 当j|x为11111111 即每种数字都选完的时候 这时候才会满足 数字个数为t或者t+1 才可以进行对ans的更新
时间复杂度 n^2 * (255) * log(n)
一道题补了两天...期间打了好久游戏...QAQ
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
#include<vector>
#include<queue>
#include<malloc.h>
using namespace std;
#define L long long
int n ;
int dp[1050][(1<<8) + 5];
int a[1050];
int b[(1<<8) + 5];
int sum[1050][9];
int main(){
scanf("%d",&n);
memset(sum,0,sizeof(sum));
int ans = 0;
int mj = (1<<8) - 1;
for(int i=0;i<=mj;i++){
int z = i;
b[z] = 0;
while(z){
if(z%2 == 1)b[i] ++;
z/=2;
}
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
for(int j=1;j<=8;j++)sum[i][j] = sum[i-1][j];
sum[i][a[i]] ++ ;
}
for(int i=1;i<=8;i++){
if(sum[n][i]>0)ans++;
}
for(int t=1;t*8<=n;t++){
memset(dp , -1 ,sizeof(dp));
dp[0][0] = 0;
for(int i=0;i<n;i++){
for(int j=0;j<=mj;j++){
if(dp[i][j] == -1)continue;
for(int k=1;k<=8;k++){
int z = (1<<(k-1));
if((z&j) == 0){
int g=(z|j);
int l = i+1;
int r = n;
int res = -1;
while(l<=r){
int mid =(l+r)/2;
if(sum[mid][k] - t > sum[i][k]){
r = mid - 1;
}
else if(sum[mid][k] - t < sum[i][k]){
l = mid + 1;
}
else {
r = mid - 1;
res = mid;
}
}
if(res != -1){
if(dp[res][g] == -1 || dp[res][g] < dp[i][j] + t){
dp[res][g] = dp[i][j] + t;
if(b[g] == 8)
ans = max(dp[res][g] , ans);
}
}
l = i+1;
r = n;
res = -1;
while(l<=r){
int mid =(l+r)/2;
if(sum[mid][k] - t - 1> sum[i][k]){
r = mid - 1;
}
else if(sum[mid][k] - t - 1< sum[i][k]){
l = mid + 1;
}
else {
r = mid - 1;
res = mid;
}
}
if(res != -1){
if(dp[res][g] == -1 || dp[res][g] < dp[i][j] + t + 1){
dp[res][g] = dp[i][j] + t + 1;
if(b[g] == 8)
ans = max(dp[res][g] , ans);
}
}
}
}
}
}
}
printf("%d\n",ans);
}
Codeforces Round #384 (Div. 2) E的更多相关文章
- 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 ...
- Codeforces Round #384 (Div. 2)D - Chloe and pleasant prizes 树形dp
D - Chloe and pleasant prizes 链接 http://codeforces.com/contest/743/problem/D 题面 Generous sponsors of ...
- Codeforces Round #384 (Div. 2) C. Vladik and fractions 构造题
C. Vladik and fractions 题目链接 http://codeforces.com/contest/743/problem/C 题面 Vladik and Chloe decided ...
- Codeforces Round #384 (Div. 2)B. Chloe and the sequence 数学
B. Chloe and the sequence 题目链接 http://codeforces.com/contest/743/problem/B 题面 Chloe, the same as Vla ...
- Codeforces Round #384 (Div. 2) A. Vladik and flights 水题
A. Vladik and flights 题目链接 http://codeforces.com/contest/743/problem/A 题面 Vladik is a competitive pr ...
- Codeforces Round #384(div 2)
A 题意:有n个机场处于一直线上,可两两到达,每个机场只可能属于两家公司中的一家(用0,1表示),现在要从a机场到b机场,可任意次转机.若机场i与机场j从属同一公司,则费用为0,否则费用为1.问最小费 ...
- Codeforces Round #384 (Div. 2) C. Vladik and fractions(构造题)
传送门 Description Vladik and Chloe decided to determine who of them is better at math. Vladik claimed ...
- Codeforces Round #384 (Div. 2) B. Chloe and the sequence(规律题)
传送门 Description Chloe, the same as Vladik, is a competitive programmer. She didn't have any problems ...
- 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 #384 (Div. 2)D-Chloe and pleasant prizes
D. Chloe and pleasant prizes time limit per test 2 seconds memory limit per test 256 megabytes input ...
随机推荐
- 下拉列表 select-option ; select-optgroup-option
HTML中的下拉列表: <select> <option value ="1">Volvo</option> <option value ...
- [转]Android样式的开发:shape篇
转载自Keegan小钢原文链接:http://keeganlee.me/post/android/20150830 Android样式的开发:shape篇Android样式的开发:selector篇A ...
- MySQL找回管理员密码
更改MySQL提示符 mysql> prompt \u@mysql \r:\b:\s 查找以my开头的数据库 mysql> show databases like 'my%' 删除用户所有 ...
- 使用vs2008搭建php扩展环境
所需要的工具或者文件: 1.php源码,去官网下载即可.http://windows.php.net/download 2.php-sdk:php 开发工具包 3.deps类库 4.Cygwin:wi ...
- python备忘--函数
1.zip函数 zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表. x = [1, 2, 3] y = [4, 5, 6] z = [7, 8, 9] xyz = zip( ...
- 解析 Linux 内核可装载模块的版本检查机制
转自:http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmodules/ 为保持 Linux 内核的稳定与可持续发展,内核在发展过程中引进了可 ...
- Pyqt+QRcode 生成 识别 二维码
1.生成二维码 python生成二维码是件很简单的事,使用第三方库Python QRCode就可生成二维码,我用Pyqt给QRcode打个壳 一.python-qrcode介绍 python-qrco ...
- .NET中RabbitMQ的使用
概述 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public ...
- GO语言中json与map的转换
直接上代码(需要引入encoding/json包) // 当前程序的包名 package main // 导入其它的包 import ( "encoding/json" " ...
- 目标跟踪_MeanShift
找到一些关于目标跟踪的资料 http://blog.csdn.net/jinshengtao/article/details/30258833 http://blog.sina.com.cn/s/bl ...