bzoj4565【HAOI2016】字符合并

4565: [Haoi2016]字符合并

Time Limit: 20 Sec  Memory Limit: 256 MB

Submit: 102  Solved: 49

[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分。

DP

f[i][j][0]和f[i][j][1]表示区间[i,j]合并为0或1的最大分数。

g[j][k]表示当前的i到j合并为k的最大分数。

然后是很麻烦的转移,详见程序。

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define N 300
using namespace std;
int n,m;
ll w[N],c[N],f[N][N][2],g[N][N],tmp[2],ans[N];
char s[N];
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	n=read();m=read();
	scanf("%s",s+1);
	F(i,0,(1<<m)-1)  c[i]=read(),w[i]=read();
	memset(f,-1,sizeof(f));
	F(i,1,n) f[i][i][s[i]-'0']=0;
	D(i,n-m+1,1)
	{
		memset(g,-1,sizeof(g));
		int now=1;
		g[i][0]=f[i][i][0];g[i][1]=f[i][i][1];
		F(j,i+1,n)
		{
			F(x,0,(1<<now)-1) if (g[j-1][x]>=0) for(int k=j;k<=n;k+=m-1)
			{
				if (f[j][k][0]>=0) g[k][x<<1]=max(g[k][x<<1],g[j-1][x]+f[j][k][0]);
				if (f[j][k][1]>=0) g[k][x<<1|1]=max(g[k][x<<1|1],g[j-1][x]+f[j][k][1]);
			}
			now++;
			if (now==m)
			{
				tmp[0]=tmp[1]=-1;
				F(x,0,(1<<m)-1) if (g[j][x]>=0) tmp[c[x]]=max(tmp[c[x]],w[x]+g[j][x]);
				f[i][j][0]=g[j][0]=tmp[0];
				f[i][j][1]=g[j][1]=tmp[1];
				now=1;
			}
		}
	}
	F(i,1,n) for(int j=i;j<=n;j+=m-1) ans[j]=max(ans[j],ans[i-1]+max(f[i][j][0],f[i][j][1]));
	printf("%lld\n",ans[n]);
}
时间: 2024-08-26 16:10:40

bzoj4565【HAOI2016】字符合并的相关文章

【BZOJ4565】 [Haoi2016]字符合并

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,w

2017.8.15 [Haoi2016]字符合并 区间dp+状压dp

[题目描述] 有一个长度为n的01串,你可以每次将相邻的k个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这k个字符确定.你需要求出你能获得的最大分数. [输入格式] 第一行两个整数n,k. 接下来一行长度为n的01串,表示初始串.输入的的相邻字符之间用一个空格隔开. 接下来2k行,每行一个字符ci和一个整数wi,ci表示长度为k的01串连成二进制后按从小到大顺序得到的第i种合并方案得到的新字符, wi表示对应的第i种方案对应获得的分数. [输出格式] 输出一个整数表示答案. [

P3736 [HAOI2016]字符合并

链接: https://www.luogu.org/recordnew/lists?uid=62242 题目描述 有一个长度为 nn 的 0101 串,你可以每次将相邻的 kk 个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这 kk 个字符确定.你需要求出你能获得的最大分数. 输入输出格式 输入格式: 第一行两个整数 n,kn,k . 接下来一行长度为 nn 的 0101 串,表示初始串.输入的的相邻字符之间用一个空格隔开. 接下来 2^k2k 行,每行一个字符 c_ici? 

「HAOI2016」字符合并

题目描述 有一个长度为 $n$ 的 $01$ 串,你可以每次将相邻的 $k$ 个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这 $k$ 个字符确定.你需要求出你能获得的最大分数. 数据范围 $1 \leq n \leq 300, \ 0 \leq c_i \leq 1, \ w_i \geq 1, \ k \leq 8$ 题解 数据范围较小,考虑区间 $dp$ , $f_{l,r,s}$ 表示 $[l,r]$ 最后合并成状态 $s$ 的最大分数,可以通过 $l,r$ 知道 $s

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 qwe H bb 0 0 0 -9 fgh rty H cc 0 0 0 -9 jkl uio 现希望根据file1和file2相同的列字符合并文件,要求如下:1.如果两个文件的第二列相同,则将file2的第三列.第四列.第五列.第六列修改为file1对应的第三列.第四列.第五列.第六列内容:2.新文件

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

字符合并 Description 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这 k 个字符确定.你需要求出你能获得的最大分数. Input Format 第一行两个整数n,k.接下来一行长度为n的01串,表示初始串. 接下来2^k行,每行一个字符ci和一个整数wi,ci表示长度为k的01串连成二进制后按从小到大顺序得到的第i种合并方案得到的新字符,wi表示对应的第i种方案对应获得的分数. 1<=n<=300,0<

04. 字符串合并与拆分写法小结

原文:04. 字符串合并与拆分写法小结 一. 字符合并 if OBJECT_ID('ConcatStr') is not null drop table ConcatStr GO create table ConcatStr ( ID int, Code varchar(10) ) GO insert into ConcatStr select 1,'XXX' union all select 1,'YYY' union all select 2,'PPP' union all select 2

Swift 实现图片转字符画的功能

本文介绍一个IOS APP , 将图片转换成ASCII字符画,使用Swift语言编写. 举个例子,我们使用著名的蕾娜照片作为原图片 经APP转换后形成的字符画,我们打印出来,效果如下: 放大她的脸部可以看到图像都是字符串组成的! 项目地址: https://github.com/ijoshsmith/swift-ascii-art 字符画原理 图像中的每个像素都对应到一个ASCII值,在这里显示为一个字符. 图像中的每个像素都会被转换成一个中间值,如下所示: 让我们一步步来分析. 首先,我们将一

标准的I/O和管道使用方法

标准的I/O和管道 程序:指令+数据 系统自带了许多二进制程序,这些二进制程序共有两部分组成,一部分是指令,一部分是数据. 指令就是指二进制程序中的内容,然而程序的运行,也需要数据来支撑. 标准输出  STDOUT  -1   standard  output 输入命令所呈现在屏幕上的内容称之为标准输出,但是不是所有的命令都有标准输出.例如cd  rm后面不跟参数时,就没有标准输出. 标准输出的默认设备就是当前终端窗口. 标准错误  STDERR  -2  standard  error 当命令