给出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的更多相关文章

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

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

  3. Codeforces Round #384 (Div. 2) C. Vladik and fractions 构造题

    C. Vladik and fractions 题目链接 http://codeforces.com/contest/743/problem/C 题面 Vladik and Chloe decided ...

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

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

  6. Codeforces Round #384(div 2)

    A 题意:有n个机场处于一直线上,可两两到达,每个机场只可能属于两家公司中的一家(用0,1表示),现在要从a机场到b机场,可任意次转机.若机场i与机场j从属同一公司,则费用为0,否则费用为1.问最小费 ...

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

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

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

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

随机推荐

  1. Keepalived日志

    默认日志存放在系统日志:/var/log/messages下 [root@lb01 /]# tail -f /var/log/messages Oct :: lb01 Keepalived_vrrp[ ...

  2. androi手机解锁引导程序

    1.重启手机进入fastboot模式  一般关机状态下按手机音量减+开机键,成功后会显示fastboot字提示. 2.查看设备信息 fastboot devices 说明:fastboot是一个工具软 ...

  3. source和./的区别

    熟悉Linux的朋友常使用·bash·.·sh·.·source·.·.·,但却并非每位朋友都知道其中的区别.我们通过下面一幅图来为大家说明白.

  4. Java 自动装箱、拆箱机制及部分源码分析

    Integer i = 10; //装箱,反编译后发现调用Integer.valueOf(int i) int t = i; //拆箱,反编译后发现调用i.intValue() public clas ...

  5. PHP面向对象讲解

    面向对象   类<------>对象 面向对象例题 理解:  减少 变量的重新定义    比如  变量前的  var   $    思路更加明确 class Yuan ----后面不加() ...

  6. 移动端touchstart、touchmove事件的基本使用

    在pc端,我们通常使用$(window).scroll()事件来监听元素的位置,来做一些入场动效,如: $(window).scroll(function(){ var panel3Move = do ...

  7. Java的RMI远程方法调用实现和应用

    最近在学习Dubbo,RMI是很重要的底层机制,RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一 ...

  8. [转载]memcached完全剖析--1. memcached的基础

    转载自:http://charlee.li/memcached-001.html 翻译一篇技术评论社的文章,是讲memcached的连载.fcicq同学说这个东西很有用,希望大家喜欢. 发表日:200 ...

  9. You don't have permission to access /index.php on this server

    <Directory /> #AllowOverride none #Require all denied</Directory>

  10. Linux学习笔记(2)-开机

    今天开始学习Linux系统. 打开虚拟机,输入密码后,令人激动的画面就蹦出来了-- Ubuntu的主要基调是橙色,给人一种蠢萌蠢萌的感觉,和Windows不同,它只在左边有一条任务栏,上面有些东西,搜 ...