【BZOJ4565】【HAOI2016】字符合并 [状压DP][区间DP]
字符合并
Time Limit: 20 Sec Memory Limit: 256 MB
[Submit][Status][Discuss]
Description
Input
Output
输出一个整数表示答案
Sample Input
101
1 10
1 10
0 20
1 30
Sample Output
HINT
1<=n<=300 ,0<=ci<=1, wi>=1, k<=8
Solution
我们显然考虑区间DP,再状态压缩一下,f[l][r][opt]表示[l, r]合成了opt的最大价值。
如果一个区间长度为len的话,最后合完会长度会变为len % (k - 1)。
转移的本质是把长度为k的区间变成0/1,分情况处理。
先枚举每一个断点pos,表示我们要把[pos, r]合成一个0/1,那么就要保证(r - pos + 1) % (k - 1) = 1,否则我们DP的时候,会把000看做是0一样转移,导致不能合成为一个0/1的合成了。
若len % (k -1) = 1,则合成完会剩下一个数,我们判断一下[l, r]能否合成一个opt的状态,若可以,则f[l][r][c[opt]] = max(f[l][r][opt] + val[opt])。注意要先拿一个变量记录下来,不能直接更新,否则会出现0状态更新了1,然后1又用0更新了的情况,导致答案过大。
最后答案显然就是max(f[1][n][opt])。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = ;
const int MOD = 1e9 + ; int n, k;
int total;
int a[ONE];
char s[ONE];
int c[ONE], val[ONE];
s64 f[ONE][ONE][ONE];
s64 Ans; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int main()
{
n = get(); k = get(); total = ( << k) - ; for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
for(int opt = ; opt <= total; opt++)
f[i][j][opt] = -; scanf("%s", s + );
for(int i = ; i <= n; i++)
a[i] = s[i] - '', f[i][i][a[i]] = ; for(int i = ; i <= total; i++)
c[i] = get(), val[i] = get(); for(int l = n; l >= ; l--)
for(int r = l; r <= n; r++)
{
if(l == r) continue; for(int pos = r - ; pos >= l; pos -= k - )
for(int opt = ; opt <= total; opt++)
{
if(f[l][pos][opt] == -) continue;
if(f[pos + ][r][] != - && (opt << ) <= total)
f[l][r][opt << ] = max(f[l][r][opt << ], f[l][pos][opt] + f[pos + ][r][]);
if(f[pos + ][r][] != - && (opt << | ) <= total)
f[l][r][opt << | ] = max(f[l][r][opt << | ], f[l][pos][opt] + f[pos + ][r][]);
} if((r - l + ) % (k - ) == || k == )
{
s64 A = -, B = -;
for(int opt = ; opt <= total; opt++)
if(f[l][r][opt] != -)
{
if(c[opt] == ) A = max(A, f[l][r][opt] + val[opt]);
if(c[opt] == ) B = max(B, f[l][r][opt] + val[opt]);
} f[l][r][] = max(f[l][r][], A);
f[l][r][] = max(f[l][r][], B);
}
} for(int opt = ; opt <= total; opt++)
Ans = max(Ans, f[][n][opt]); printf("%lld", Ans); }
- 制作
【BZOJ4565】【HAOI2016】字符合并 [状压DP][区间DP]的更多相关文章
- BZOJ4565 [Haoi2016]字符合并
题意 有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这\(k\)个字符确定.你需要求出你能获得的最大分数. \(n ...
- [BZOJ4565][HAOI2016]字符合并(区间状压DP)
https://blog.csdn.net/xyz32768/article/details/81591955 首先区间DP和状压DP是比较明显的,设f[L][R][S]为将[L,R]这一段独立操作最 ...
- 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 ...
- BZOJ4565 HAOI2016字符合并(区间dp+状压dp)
设f[i][j][k]为将i~j的字符最终合并成k的答案.转移时只考虑最后一个字符是由哪段后缀合成的.如果最后合成为一个字符特殊转移一下. 复杂度看起来是O(n32k),实际常数极小达到O(玄学). ...
- 【BZOJ】4565: [Haoi2016]字符合并
4565: [Haoi2016]字符合并 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 690 Solved: 316[Submit][Status ...
- 洛谷 1063 dp 区间dp
洛谷 1063 dp 区间dp 感觉做完这道提高组T1的题之后,受到了深深的碾压,,最近各种不在状态.. 初看这道题,不难发现它具有区间可并性,即(i, j)的最大值可以由(i, k) 与 (k+1, ...
- 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压
考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...
- 【BZOJ4565】 [Haoi2016]字符合并
Description 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字 符和分数由这 k 个字符确定.你需要求出你能获得的最大分数. I ...
- [Haoi2016]字符合并 题解
tijie 时间限制: 2 Sec 内存限制: 256 MB 题目描述 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字 符和分数由这 ...
随机推荐
- 第二章 script元素
<script>元素 async:可选.表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本.只对外部脚本文件有效. charset:可选.表示通过 ...
- oracle & 的用法!
/*select * from emp_bak where deptno = &"Department number" order by ename; select * f ...
- mysql子查询批量找id最大的
$sql = "select a.id as max_id,a.uid from(SELECT `uid`, idFROM (`users_level_change_log`)WHERE ` ...
- Java对象空间分配流程
对象空间分配流程如下: 针对这个流程,分别解释一下每一个选项的使用场景. 栈上分配: 栈上分配的基础在于逃逸分析,逃逸分析可以得到三种对象的逃逸状态. 全局逃逸:一个对象的引用逃出了方法或者线程. ...
- 公告:请访问我的个人博客新站点——www.huangshujia.me
我的个人博客现在在(http://www.huangshujia.me/)cnblog这里不会做任何更新了.或者关注我的个人公众号:碱基矿工
- bzoj2429- 聪明的猴子
题意其实就是说有很多个点,求一组边把它们都连接起来,并且最大的那条边最小.很明显这就是一个最小生成树,是一颗保证最长边最短的树. 代码 刚刚学了个Borůvka算法,于是写了两个. Borůvka # ...
- 精通android学习笔记(一)---广播
普通广播:sendBroadcast 有序广播:sendOrderedBroadcast,有序广播优先级可以再manifest中设置,数值越大,最先收到.-1000~1000 <receiver ...
- P1053 篝火晚会
题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有nnn个同学,编号从111到nnn.一开始 ...
- Doves and bombs UVA - 10765(统计割顶所连接的连通块的数量)
题意:给定一个n个点的连通的无向图,一个点的“鸽子值”定义为将它从图中删去后连通块的个数. 求对应的点 和 每个点的“鸽子值” 用一个数组在判断割顶的那个地方 累加标记一下所连接的连通块的数量即可 初 ...
- 前端跨域问题相关知识详解(原生js和jquery两种方法实现jsonp跨域)
1.同源策略 同源策略(Same origin policy),它是由Netscape提出的一个著名的安全策略.同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正 ...