bzoj 4565 字符合并
Written with StackEdit.
Description
有一个长度为 \(n\) 的 \(01\) 串,你可以每次将相邻的 \(k\) 个字符合并,得到一个新的字符并获得一定分数。得到的新字符和分数由这\(k\) 个字符确定。你需要求出你能获得的最大分数。
Input
第一行两个整数\(n,k\)。接下来一行长度为n的01串,表示初始串。接下来\(2^k\)行,每行一个字符\(c_i\)和一个整数\(w_i\),\(c_i\)表示长度为\(k\)的\(01\)串连成二进制后按从小到大顺序得到的第i种合并方案得到的新字符,\(w_i\)表示对应的第\(i\)种方案对应获得的分数。
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
\(1\leq n\leq 300,0\leq ci\leq 1,1\leq w_i,k\leq8.\)
Solution
并不会做...于是临摹zxTLEdalao的题解...然后自己似乎懂了一点.
- 这道题\(k\leq8\),做出一副状压的嘴脸虽然的确也用到了状压,但解决本题的核心在于区间\(dp\).
- 考虑令\(f[l][r][p]\)表示将原串\([l,r]\)合并为\(t\)能获得的最大收益.
- 显然是满足无后效性的.合并起来之后就不再关心合并过程了.
- 枚举中间的端点\(mid\),使得\(mid\)右边的子串合并起来是\(t\)的最后一位数字,左边的子串合并起来是\(t\)前面的数字.
- 注意到,合并时只能连续的\(k\)个数字合并,那么可以合并成\(1\)位数字的子串长度一定为\(1,k,2k-1......\),枚举\(mid\)时相差为\(k-1\)即可.
- 特殊情况:从\(l\)到\(r\)恰好有\(k\)个数,这时我们直接合并,用辅助数组\(g\)求出此时的\(f\),
#include<bits/stdc++.h>
#define inf (1LL<<60)//防止相加爆long long
using namespace std;
typedef long long ll;
inline ll read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
{
fh=-1;
jp=getchar();
}
while (jp>='0'&&jp<='9')
{
out=out*10+jp-'0';
jp=getchar();
}
return out*fh;
}
inline void upd(ll &x,ll y)
{
x=max(x,y);
}
const int MAXN=329;
const int MAXS=(1<<8)+10;
int a[MAXN];
int n,k,lim;
char buf[MAXN];
ll w[MAXS],c[MAXS];
ll f[MAXN][MAXN][MAXS];//f[l][r][k]:将原串的[l,r]合并为t能获得的最大分数
int main()
{
n=read(),k=read();
scanf("%s",buf+1);
for(int i=1;i<=n;++i)
a[i]=(buf[i]=='1');
lim=(1<<k)-1;
for(int i=0;i<=lim;++i)
c[i]=read(),w[i]=read();
ll ans=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
for(int p=0;p<=lim;++p)
f[i][j][p]=-inf;
for(int i=n;i>=1;--i)
for(int j=i;j<=n;++j)
{
if(i==j)
{
f[i][j][a[i]]=0;
continue;
}
int len=j-i;
len%=k-1;
if(!len)
len=k-1;
for(int mid=j;mid>i;mid-=k-1)
for(int op=0;op<(1<<len);++op)
{
upd(f[i][j][op<<1],f[i][mid-1][op]+f[mid][j][0]);
upd(f[i][j][op<<1|1],f[i][mid-1][op]+f[mid][j][1]);
}
if(len==k-1)
{
ll g[2];
g[0]=g[1]=-inf;
for(ll op=0;op<(1<<k);++op)
upd(g[c[op]],f[i][j][op]+w[op]);
f[i][j][0]=g[0];
f[i][j][1]=g[1];
}
}
for(int i=0;i<=lim;++i)
upd(ans,f[1][n][i]);
printf("%lld\n",ans);
return 0;
}
bzoj 4565 字符合并的更多相关文章
- 【BZOJ】4565: [Haoi2016]字符合并
4565: [Haoi2016]字符合并 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 690 Solved: 316[Submit][Status ...
- 「BZOJ 4565」「HAOI 2016」字符合并「区间状压DP」
题意 给一个长度为\(n(\leq 300)\)的\(01\)串,每次可以把\(k(\leq 8)\)个相邻字符合并,得到新字符和一定分数,最大化最后的得分 题解 考虑设计dp:\(dp[S][i][ ...
- Linux:不同文件相同列字符合并文件(awk函数)
存在file1.txt,其内容如下: H aa 0 0 1 -9 H bb 0 0 2 -9 H cc 0 0 2 -9 存在file2.txt,其内容如下: H aa 0 0 0 -9 asd qw ...
- SQL SERVER 字符合并多行为一列
[字符合并多行为一列] 思路1:行转列,在与字符拼接(适用每组列数名相同) 思路2:转xml,去掉多余字符(适用所有) 假设兴趣表Hobbys Name Hobby 小张 打篮球 小张 踢足球 Nam ...
- 【BZOJ4565】【HAOI2016】字符合并 [状压DP][区间DP]
字符合并 Time Limit: 20 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 有一个长度为 n 的 01 串,你 ...
- BZOJ4565 [Haoi2016]字符合并
题意 有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这\(k\)个字符确定.你需要求出你能获得的最大分数. \(n ...
- 「HAOI2016」字符合并
「HAOI2016」字符合并 题意: 有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这\(k\)个字符确定.你 ...
- [Haoi2016]字符合并 题解
tijie 时间限制: 2 Sec 内存限制: 256 MB 题目描述 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字 符和分数由这 ...
- 『字符合并 区间dp 状压dp』
字符合并 Description 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这 k 个字符确定.你需要求出你能获得的最大分 ...
随机推荐
- netty3---传统IO,NIO,nettyIO
传统: NIO: nettyIO: 每个服务生负责一个区域,每个服务生是一个线程.
- 体系编程、SOC编程那些事儿
转:https://blog.csdn.net/yueqian_scut/article/details/49968897 笔者将从芯片IC的系统设计的角度去诠释如何掌握体系编程和SOC编程.笔者有超 ...
- HCNP学习笔记之TCP中FLAGS字段SYN, FIN, ACK, PSH, RST, URG
在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG. 其中,对于我们日常的分析有用的就是前面的五个字段. 含义: SYN 表示建立连接, ...
- JMS、MQ、ActiveMQ
JMS 的一个标准或者说是一个协议. 通常用于企业级应用的消息传递. 主要有topic 消息(1 对多), queue 消息(1对1). ActiveMQ 是一个JMS 的实现, apache 出的. ...
- Linux系统crontab定时调度Python脚本
Linux系统crontab定时调度Python脚本 一.Python脚本随Linux开机自动运行 #Python脚本:/home/edgar/auto.py #用root权限编辑以下文件:/etc/ ...
- Linux系统运行级别配置
Linux的运行级别 Linux的运行级别有七种,可以通过查看/etc/inittab文件进行了解: Level0:系统停机状态,默认系统运行级别不能设置为0,否则系统不能正常启动: Level1:单 ...
- 关于使用UniForm以其他控件为Parent时应该注意的问题
关于使用UniForm以其他控件为Parent时应该注意的问题: 1,不能在其他组件的oncreate,onbeforeshow,onshow等事件中来生成这样的uniform,否则其上的组件不能显示 ...
- springBean参数注入的几个方法
1.普通方式注入 applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> < ...
- java-ConcurrentLinkedQueue 简单使用
import java.util.concurrent.ConcurrentLinkedQueue; public class CacheTest { /** * * offer(E e) 将指定元素 ...
- KNN 算法,以及与Kmeans的简单对比
KNN与Kmeans感觉没啥联系,但是名字挺像的,就拿来一起总结一下吧. 初学者的总结. KNN是监督学习,Kmeans是无监督学习. KNN用于分类,Kmeans用于聚类. 先说KNN: 对于KNN ...