2018.10.25 bzoj4565: [Haoi2016]字符合并(区间dp+状压)
传送门
当看到那个k≤8k\le 8k≤8的时候就知道需要状压了。
状态定义:f[i][j][k]f[i][j][k]f[i][j][k]表示区间[i,j][i,j][i,j]处理完之后的状态为kkk时的最大贡献。
由于每次合并会减少K−1K-1K−1个,因此0<k≤K−10<k\le K-10<k≤K−1。
然后转移的时候不用一个一个转移。
两次转移的断点的距离需要保证是k−1k-1k−1,因为这样子肯定不必之前距离不为k−1k-1k−1时更优。
注意处理特殊情况(整个区间刚好可以被消玩)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,k,up,s[305],sta[260];
ll f[305][305][260],w[260],ans=0;
char S[305];
inline ll read(){
ll ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int main(){
n=read(),k=read(),up=1<<k,memset(f,-1,sizeof(f));
scanf("%s",S+1);
for(int i=1;i<=n;++i)s[i]=S[i]-'0';
for(int i=0;i<up;++i)sta[i]=read(),w[i]=read();
for(int i=1;i<=n;++i)f[i][i][s[i]]=0;
for(int Len=1;Len<n;++Len)
for(int l=1;l+Len<=n;++l){
int r=l+Len,len=Len;
while(len>k-1)len-=k-1;
for(int m=r;m>l;m-=k-1)for(int stat=0;stat<(1<<len);++stat)
if(~f[l][m-1][stat]){
if(~f[m][r][0])f[l][r][stat<<1]=max(f[l][r][stat<<1],f[l][m-1][stat]+f[m][r][0]);
if(~f[m][r][1])f[l][r][stat<<1|1]=max(f[l][r][stat<<1|1],f[l][m-1][stat]+f[m][r][1]);
}
if(len==k-1){
ll tmp[2];
tmp[0]=tmp[1]=-1;
for(int stat=0;stat<up;++stat)if(~f[l][r][stat])tmp[sta[stat]]=max(tmp[sta[stat]],f[l][r][stat]+w[stat]);
f[l][r][0]=tmp[0],f[l][r][1]=tmp[1];
}
}
for(int i=0;i<up;++i)ans=max(ans,f[1][n][i]);
cout<<ans;
return 0;
}
2018.10.25 bzoj4565: [Haoi2016]字符合并(区间dp+状压)的更多相关文章
- 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压
考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...
- 『字符合并 区间dp 状压dp』
字符合并 Description 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这 k 个字符确定.你需要求出你能获得的最大分 ...
- [BZOJ4565][HAOI2016]字符合并(区间状压DP)
https://blog.csdn.net/xyz32768/article/details/81591955 首先区间DP和状压DP是比较明显的,设f[L][R][S]为将[L,R]这一段独立操作最 ...
- BZOJ4565 [Haoi2016]字符合并
题意 有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这\(k\)个字符确定.你需要求出你能获得的最大分数. \(n ...
- 2018.10.22 bzoj4380: [POI2015]Myjnie(区间dp)
传送门 区间dp好题. f[i][j][k]f[i][j][k]f[i][j][k]表示区间[i,j][i,j][i,j]最小值为kkk时的最大贡献. 然后可以枚举端点转移. 当时口胡到这儿就不会了. ...
- BZOJ4565 HAOI2016字符合并(区间dp+状压dp)
设f[i][j][k]为将i~j的字符最终合并成k的答案.转移时只考虑最后一个字符是由哪段后缀合成的.如果最后合成为一个字符特殊转移一下. 复杂度看起来是O(n32k),实际常数极小达到O(玄学). ...
- 2018.10.20 bzoj1068: [SCOI2007]压缩(区间dp)
传送门 这题转移很妙啊. f[l][r][1/0]f[l][r][1/0]f[l][r][1/0]表示对于区间[l,r][l,r][l,r]有/无重复的机会时压缩的最小值. 那么可以从三种情况转移过来 ...
- 2018.10.25 atcoder Leftmost Ball(计数dp+组合数学)
传送门 dp妙题啊. 我认为DZYODZYODZYO已经说的很好了. 强制规定球的排序方式. 然后就变成了一个求拓扑序数量的问题. 代码: #include<bits/stdc++.h> ...
- 2018.10.24 bzoj3195: [Jxoi2012]奇怪的道路(状压dp)
传送门 f[i][j][k]f[i][j][k]f[i][j][k]表示前iii个点连了jjj条边,第i−K+1i-K+1i−K+1~iii个点连边数的奇偶性为kkk时的方案数. 转移规定只能从后向前 ...
随机推荐
- string类的一些函数方法
1.请查看String.equals()方法的实现代码,注意学习其实现方法: (1)源程序: public class StringEquals { /** * @param args the com ...
- NET Runtime version 2.0.50727.42 - 执行引擎错误 或者无法创建应用程序域
server2003操作系统 IIS运行应用程序报错,应用程序事件查看器详细: NET Runtime version 2.0.50727.42 - 执行引擎错误 或者无法创建应用程序域 解决方法:卸 ...
- 微信小程序模板中使用循环
原创文章 本篇介绍如何在模板里使用循环. 方法一: template.wxml,该文件内容为: <template name="msgItem1"> <block ...
- solrj 测试连接 6.6.5solr集群
我开始环境是 linux上是6.6.5 pom也是6.6.5 按照学习视频的demo,他用的是4点几的solr,我换成了6点几的,没有CloudSolrServer 只有CloudSolrClie ...
- 点评10款Github上最火爆的国产开源项目
衡量一个开源产品好不好,看看产品在Github的Star数量就知道了.由此可见,Github已经沦落为开源产品的“大众点评”了. 一个开源产品希望快速的被开发者知道.快速的获取反馈,放到Github上 ...
- 单元测试使用spring注解获取bean
在实际项目开发中经常会有单元测试,单元测试中经常会用类似这样的代码片段获取spring管理的bean @Test public void testSendEmail(){ MessageService ...
- python之初接触
编程语言相关 1什么是编程语言 编程语言即语言,语言的本质就是沟通,因而编程语言与英语 .法语.日语等所有语言并无区别,只不过英语是人与人之间沟通的介质,而编程语言则是程序员与计算机沟通的介质. 程序 ...
- 如何搭建http服务仓库
1.拷贝仓库repo-A文件到服务器/media/D: 2.通过createrepo_c 生成仓库rpm信息数据 cd repo-A createrepo . 3.chmod -R 775 repo ...
- BZOJ4326或洛谷2680 运输计划
BZOJ原题链接 洛谷原题链接 用\(LCA\)初始化出所有运输计划的原始时间,因为答案有单调性,所以二分答案,然后考虑检验答案. 很容易想到将所有超出当前二分的答案的运输计划所经过的路径标记,在这些 ...
- Luogu1070-道路游戏-动态规划
Solution 用对角线的前缀和快速进行转移,复杂度$O(N^3)$, 洛谷神机太快了$N^3$都能过 然而正解是单调队列优化, 能优化到$O(N^2)$,然而我弱得什么都不会 Code #incl ...