bzoj-4565-区间dp+状压
4565: [Haoi2016]字符合并
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 542 Solved: 253
[Submit][Status][Discuss]
Description
Input
Output
输出一个整数表示答案
Sample Input
101
1 10
1 10
0 20
1 30
Sample Output
//第3行到第6行表示长度为2的4种01串合并方案。00->1,得10分,01->1得10分,10->0得20分,11->1得30分。
HINT
Source
有很多细节,递推方程想出来了但最后还是看了题解才知道具体的操作。f[i][j][S]表示区间[i,j]合并成状态S获得的最大价值,一开始有一点想不通,比如'1','01','001'用二进制表示都是1,我们怎么识别的,有一个重要的性质是一个长度为k的区间完全合并后的长度就是x=n%(k-1)?n%(k-1):k-1。知道了这点就很nice了。显然一个区间肯定要完全合并才能使得价值最大。对于一个区间,考虑枚举分割点,我们可以枚举合并后最右侧的那一个数来分割这个区间,换句话说就是把[i,j]=[i,m-1]+[m,j] , [m,j]完全合并后得到一个元素,这个m可以不断-(k-1)枚举得到,由于右侧的区间大小不断的+(k-1),相当于左边的区间大小不断地-(k-1),所以这两个子区间完全合并后的元素个数s1,s2是一定的且s2==1。最后一个数可能是0/1,
得到方程 f[i][j][S<<1]=max(f[i][j][S<<1],f[i][m-1][S]+f[m][j][0])
f[i][j][S<<1|1]=max(f[i][j][S<<1|1],f[i][m-1][S]+f[m][j][1]) //注意这些状态必须合法才可转移
要注意s1的范围是[1,k-1],当s1=k-1时s1+s2=k,此时还可以再进行合并为一个元素,需要计算一下f[i][j][0/1]。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define INF 0x3f3f3f3f 5 LL f[310][310][(1<<8)+20]; 6 char s[310]; 7 int b[(1<<8)+20]; 8 LL c[(1<<8)+20]; 9 int main(){ 10 int n,m,k,i,j; 11 scanf("%d%d",&n,&k); 12 scanf("%s",s+1); 13 for(i=0;i<(1<<k);++i) 14 scanf("%d%lld",b+i,c+i); 15 memset(f,-INF,sizeof(f)); 16 LL inf=f[0][0][0]; 17 for(i=1;i<=n;++i) f[i][i][s[i]-'0']=0; 18 for(int len=2;len<=n;++len){ 19 for(i=1;i+len-1<=n;++i){ 20 j=i+len-1; 21 22 int l=(j-i)%(k-1); 23 if(!l) l=k-1; 24 for(int las=j;las>=i;las-=k-1){ 25 for(int S=0;S<(1<<l);++S){ 26 if(f[i][las-1][S]==inf) continue; 27 if(f[las][j][0]!=inf) 28 f[i][j][S<<1]=max(f[i][j][S<<1],f[i][las-1][S]+f[las][j][0]); 29 if(f[las][j][1]!=inf); 30 f[i][j][S<<1|1]=max(f[i][j][S<<1|1],f[i][las-1][S]+f[las][j][1]); 31 } 32 } 33 if(l==k-1){ 34 LL g[2]={inf,inf}; 35 for(int S=0;S<(1<<k);++S){ 36 if(f[i][j][S]!=inf){ 37 g[b[S]]=max(g[b[S]],f[i][j][S]+c[S]); 38 } 39 } 40 f[i][j][0]=g[0]; 41 f[i][j][1]=g[1]; 42 } 43 } 44 } 45 LL ans=0; 46 int l=n%(k-1)?n%(k-1):k-1; 47 for(i=0;i<(1<<l);++i) 48 ans=max(ans,f[1][n][i]); 49 cout<<ans<<endl; 50 return 0; 51 }
转载于:https://www.cnblogs.com/zzqc/p/9048616.html
bzoj-4565-区间dp+状压相关推荐
- 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压
考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...
- 【BZOJ】1076 [SCOI2008]奖励关 期望DP+状压DP
[题意]n种宝物,k关游戏,每关游戏给出一种宝物,可捡可不捡.每种宝物有一个价值(有负数).每个宝物有前提宝物列表,必须在前面的关卡取得列表宝物才能捡起这个宝物,求期望收益.k<=100,n&l ...
- BZOJ 2073: [POI2004]PRZ( 状压dp )
早上这道题没调完就去玩NOI网络同步赛了.... 状压dp , dp( s ) 表示 s 状态下所用的最短时间 , 转移就直接暴力枚举子集 . 可以先预处理出每个状态下的重量和时间的信息 . 复杂度是 ...
- BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )
状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...
- BZOJ 2004 公交线路(状压DP+矩阵快速幂)
注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...
- bzoj 2073:[POI2004]PRZ 状压DP
Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍 ...
- BZOJ 2560: 串珠子 (状压DP+枚举子集补集+容斥)
(Noip提高组及以下),有意者请联系Lydsy2012@163.com,仅限教师及家长用户. 2560: 串珠子 Time Limit: 10 Sec Memory Limit: 128 MB Su ...
- #3864. Hero meet devil dp套dp + 状压 + 状态机
传送门 文章目录 题意: 思路: 题意: 给你一个只包含ACGTACGTACGT的串sss,再给你一个mmm,第iii行输出有多少个长度为mmm且只包含ACGTACGTACGT的串与sss的lcslc ...
- [转]状态压缩dp(状压dp)
状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的 ...
- CF 221 C Circling Round Treasures - dp - 状压
题目大意: 给你一张网个图,每个位置是空地.障碍.炸弹.宝藏.起点之一. 规划一条从其点出发不包含炸弹的闭合路线(回路),并可获得最大的利润. 利润定义为路线内部的宝藏收益(可能为负数)之和减去路径长 ...
最新文章
- echarts数据变了不重新渲染,以及重新渲染了前后数据会重叠渲染的问题
- 转载:一致性 hash 算法( consistent hashing )
- 爱晚红枫的博客配色----绿野仙踪
- 两个byte[]拼接
- 重命名数据库表空间和数据文件
- node oauth2验证_如何设置和使用护照OAuth Facebook身份验证(第2部分)| Node.js
- Building A New Barn(POJ-3269)
- 父亲节,程序员几条代码硬核示爱
- Pandas DateOffset
- windows qt 使用openssl API
- 手机丢了,支付宝和微信里面的钱该怎么办?
- 循环数组的动态规划问题
- Ubuntu新版发布周期
- 在谷歌浏览器中安装IE Tab插件
- Wolf从零学编程-用Python打造简单加密程序(一)
- ffmpeg解析出的视频参数PAR,DAR,SAR的意义
- MySQL之Explain
- xmind设计测试用例以及与云效平台的交互
- 程序媛的2013总结以及2014展望
- k近邻算法——kd树