4565: [Haoi2016]字符合并

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 542  Solved: 253
[Submit][Status][Discuss]

Description

有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数。得到的新字
符和分数由这 k 个字符确定。你需要求出你能获得的最大分数。

Input

第一行两个整数n,k。接下来一行长度为n的01串,表示初始串。接下来2k行,每行一个字符ci和一个整数wi,ci
表示长度为k的01串连成二进制后按从小到大顺序得到的第i种合并方案得到的新字符,wi表示对应的第i种方案对应
获得的分数。1<=n<=300,0<=ci<=1,wi>=1,k<=8

Output

输出一个整数表示答案

Sample Input

3 2
101
1 10
1 10
0 20
1 30

Sample Output

40
//第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]。

  

 #include<bits/stdc++.h>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
LL f[][][(<<)+];
char s[];
int b[(<<)+];
LL c[(<<)+];
int main(){
int n,m,k,i,j;
scanf("%d%d",&n,&k);
scanf("%s",s+);
for(i=;i<(<<k);++i)
scanf("%d%lld",b+i,c+i);
memset(f,-INF,sizeof(f));
LL inf=f[][][];
for(i=;i<=n;++i) f[i][i][s[i]-'']=;
for(int len=;len<=n;++len){
for(i=;i+len-<=n;++i){
j=i+len-; int l=(j-i)%(k-);
if(!l) l=k-;
for(int las=j;las>=i;las-=k-){
for(int S=;S<(<<l);++S){
if(f[i][las-][S]==inf) continue;
if(f[las][j][]!=inf)
f[i][j][S<<]=max(f[i][j][S<<],f[i][las-][S]+f[las][j][]);
if(f[las][j][]!=inf);
f[i][j][S<<|]=max(f[i][j][S<<|],f[i][las-][S]+f[las][j][]);
}
}
if(l==k-){
LL g[]={inf,inf};
for(int S=;S<(<<k);++S){
if(f[i][j][S]!=inf){
g[b[S]]=max(g[b[S]],f[i][j][S]+c[S]);
}
}
f[i][j][]=g[];
f[i][j][]=g[];
}
}
}
LL ans=;
int l=n%(k-)?n%(k-):k-;
for(i=;i<(<<l);++i)
ans=max(ans,f[][n][i]);
cout<<ans<<endl;
return ;
}

bzoj-4565-区间dp+状压的更多相关文章

  1. 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压

    考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...

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

  3. 『字符合并 区间dp 状压dp』

    字符合并 Description 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这 k 个字符确定.你需要求出你能获得的最大分 ...

  4. BZOJ4565 HAOI2016字符合并(区间dp+状压dp)

    设f[i][j][k]为将i~j的字符最终合并成k的答案.转移时只考虑最后一个字符是由哪段后缀合成的.如果最后合成为一个字符特殊转移一下. 复杂度看起来是O(n32k),实际常数极小达到O(玄学). ...

  5. BZOJ 2064: 分裂 [DP 状压 转化]

    传送门 题意:一开始$n$块面积最后$m$块面积,面积和相等每次可以分裂或者合并,问最少几次 昨天忘发了... 不会.... 考虑最差情况,$n+m-2$所有先合并再分裂 发现只有当前后两个子集相等时 ...

  6. 【BZOJ】1076 [SCOI2008]奖励关 期望DP+状压DP

    [题意]n种宝物,k关游戏,每关游戏给出一种宝物,可捡可不捡.每种宝物有一个价值(有负数).每个宝物有前提宝物列表,必须在前面的关卡取得列表宝物才能捡起这个宝物,求期望收益.k<=100,n&l ...

  7. 【HDU】4352 XHXJ's LIS(数位dp+状压)

    题目 传送门:QWQ 分析 数位dp 状压一下现在的$ O(nlogn) $的$ LIS $的二分数组 数据小,所以更新时直接暴力不用二分了. 代码 #include <bits/stdc++. ...

  8. BZOJ 1087 题解【状压DP】

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3112  Solved: 1816[Submit][ ...

  9. BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...

  10. BZOJ 4057: [Cerc2012]Kingdoms( 状压dp )

    状压dp.... 我已开始用递归结果就 TLE 了... 不科学啊...我dp基本上都是用递归的..我只好改成递推 , 刷表法 将全部公司用二进制表示 , 压成一个数 . 0 表示破产 , 1 表示没 ...

随机推荐

  1. hdu2196 Computer【树形DP】【换根法】

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  2. Mongo Rocks 在SSD盘上表现优秀,专门为SSD盘的优化

    2017 · MongoDB深圳用户组大会全记录 | MongoDB中文社区http://www.mongoing.com/2017/04/24/mongodb-shenzhen-user-group ...

  3. nginx ---refine---按需时间/流量进行调整后台服务器---geocity,proxypass

    原理相当于配置文件在启动时进行编译,proxyPass http://mydomain/path/xxxx这种方式是编译成静态的,直接替换成它解析到的ip/vip,只有重新启动时才会重新解析. 而 s ...

  4. 第1章 1.6计算机网络概述--OSI参考模型

    ISO七层模式:国际标准组织对互联网通信规则进行的定义. 7.应用层:所有能产生网络流量的程序,如:QQ. 6.表示层:传输前对数据进行进行处理,是一种数据处理的规则,如:加密.压缩.传输二进制(图片 ...

  5. python 的 import 使用规则

    对于含有 __init__.py 的目录(如adir),其实它就是一个package,它的子目录如果也包含 __init__.py,则只要将 adir 加入 sys.path,则它的字目录就不用加了, ...

  6. Incorrect datetime value

    今天在开发库上给一个表添加字段时候,发现居然报错: root@DB 06:14:42>ALTER TABLE `DB`.` user` ADD COLUMN `status_mode` TINY ...

  7. kafka详解

    一.基本概念 介绍 Kafka是一个分布式的.可分区的.可复制的消息系统.它提供了普通消息系统的功能,但具有自己独特的设计. 这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统术语:Kafk ...

  8. 学习Mysql的记录贴 记录的内容是 指令的试用

    前言:操作系统是WIn7 64位 旗舰版   ,Mysql的版本是mysql-5.7.10-winx64 是社区版 就是所谓的最后的免费版本. 下载后 解压 然后配置my.ini文件. ××××××× ...

  9. SpringData_PagingAndSortingRepository接口

    该接口提供了分页与排序功能 Iterable<T> findAll(Sort sort); //排序 Page<T> findAll(Pageable pageable); / ...

  10. hdu 5017

    好恶心的题 #include <cstdio> #include <string.h> #include <algorithm> #include <cmat ...