tijie

时间限制: 2 Sec  内存限制: 256 MB

题目描述

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

输入

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

输出

输出一个整数表示答案

样例输入

3 2
101
1 10
1 10
0 20
1 30

样例输出

40
//第3行到第6行表示长度为2的4种01串合并方案。00->1,得10分,01->1得10分,10->0得20分,11->1得30分。
  这道题当时是按照搜索或动归去做的,然而,想不出动归状态咋搞啊,于是乎,花了不到半个小时打了一个MLE的爆搜果断挂了,爆零。
  其实正解真的是DP,只是状态蛮有意思的,这是一种区间动归的思想,因为他合并只是一段串合并,对左右两端的串无直接影响而n,k也不大,因此我们考虑一下状压,当时不是没想过这点,只是压什么,怎么压是个问题,我们自然是不可能去压全串的状态,但我们可以稍微算一下,区间动归所需的状态数组加上状压应是3维,300*300=90000,如果以一般数组大小(个人理解是1000000~20000000)的话大约还能压100~200左右,那么就是256——2^8了,2^8有什么实际意义呢8就是k的最小值,我们就可以根据这个信息猜到可能是要去压8位。
  那么压8位的化状态数组就是f[301][301][1<<8]了,f[i][j][s]就表示从i到j之间进行字符串替换后成为s的状态所能得到的最大值,转移也就成为了区间动归套路,首先第一层循环一定是枚举区间长度,用小区间去维护大区间,第二层就是枚举左端点了,第三层也就是枚举中间值,由于还有状压,第四层就是枚举状态了,由于我们每次合并都是以k为长度,所以右端点不必挨个枚举,每次减去k-1即可。
  然后如果len=k-1,说明该串可以被合并,我们就去找每个合法状态中转化为0或1中最大的两个,由于最终只能变化为0或1,这样无疑是正确的,然后,统计一下最优答案就好了。
  
 #include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<string>
#include<cmath>
using namespace std;
int n,k;
long long b[<<],c[<<];
long long f[][][<<];
char a[];
int main(){
// freopen("merge.in","r",stdin);
// freopen("merge.out","w",stdout);
memset(f,-0x7f,sizeof(f));
scanf("%d%d",&n,&k);
scanf("%s",a);
for(int i=;i<=n;i++)
{
f[i][i][a[i-]-'']=;
}
for(int i=;i<(<<k);i++)
{
scanf("%lld%lld",&b[i],&c[i]);
}
for(int l=;l<=n;l++)
{
for(int i=;i<=n-l+;i++)
{
int j=i+l-;
int len=j-i;
while(len>=k){
len-=k-;
}
for(int t=j;t>i;t-=k-)
{
for(int s=;s<(<<(len));s++)
{
if(f[i][t-][s]!=f[][][]&&f[t][j][]!=f[][][])
{
f[i][j][s<<]=max(f[i][j][s<<],f[i][t-][s]+f[t][j][]);
}
if(f[i][t-][s]!=f[][][]&&f[t][j][]!=f[][][])
{
f[i][j][s<<|]=max(f[i][j][s<<|],f[i][t-][s]+f[t][j][]);
}
}
}
if(len==k-)
{
long long g[];
g[]=g[]=f[][][];
for(int s=;s<(<<k);s++)
{
if(f[i][j][s]!=f[][][])
{
g[b[s]]=max(g[b[s]],f[i][j][s]+c[s]);
}
}
f[i][j][]=g[];
f[i][j][]=g[];
}
}
}
long long ans=f[][][];
for(int i=;i<(<<k);i++)
{
ans=max(ans,f[][n][i]);
}
printf("%lld\n",ans);
//while(1);
return ;
}

 

[Haoi2016]字符合并 题解的更多相关文章

  1. 【BZOJ】4565: [Haoi2016]字符合并

    4565: [Haoi2016]字符合并 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 690  Solved: 316[Submit][Status ...

  2. 题解 [HAOI2016]字符合并

    题目传送门 Description 有一个长度为 \(n\) 的 \(01\) 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数. 得到的新字符和分数由这 k 个字符确定.你需要 ...

  3. BZOJ4565 [Haoi2016]字符合并

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

  4. 【BZOJ4565】 [Haoi2016]字符合并

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

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

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

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

  7. [BZOJ4565][HAOI2016]字符合并(区间状压DP)

    https://blog.csdn.net/xyz32768/article/details/81591955 首先区间DP和状压DP是比较明显的,设f[L][R][S]为将[L,R]这一段独立操作最 ...

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

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

  9. [HAOI2016]字符合并

    Luogu3736 很容易想到直接DP,关键是枚举顺序. \(1.\)设后一段构成最后一个点,前一段构成前面的点,那么能得到\(1\)个点的数量要求 : \(1,k,2k-1...\)相差\(k-1\ ...

随机推荐

  1. WPF开发之限制输入的控件---------转自CDSN

    原文地址 http://blog.csdn.net/ghosind/article/details/51627601 作者 ghosind 一,正则表达式过滤字符串 if (RegexString = ...

  2. Java FTP 基本操作

    最近工作中用到了 FTP 相关的操作,所以借此机会了解了下具体内容. FTP基础 关于 FTP 基础推荐阅读<使用 Socket 通信实现 FTP 客户端程序>,其中需要特别注意的是主动模 ...

  3. Win8 Metro(C#)数字图像处理--2.39二值图像投影

    原文:Win8 Metro(C#)数字图像处理--2.39二值图像投影  [函数名称]   二值图像投影         ImageProjection(WriteableBitmap src) ...

  4. 第一个kotlin程序

    class ccc { companion object { @JvmStatic fun main(args: Array<String>) { println("hello! ...

  5. Win10《芒果TV》商店内测版更新至v3.7.65.0:跨平台UI新体验,铺路SP

    Win10<芒果TV - Preview>是Win10<芒果TV>官方唯一指定内测预览版,最新的改进和功能更新将会在此版本优先体验. 春去夏来,初心犹在,Win10<芒果 ...

  6. SqlServer 可更新订阅队列读取器代理错误:试图进行的插入或更新已失败

    原文:SqlServer 可更新订阅队列读取器代理错误:试图进行的插入或更新已失败 今天发现队列读取器代理不停地尝试启动但总是出错: 其中内容如下: 队列读取器代理在连接"Publicati ...

  7. 算法之--字符串包含【python实现】

    题目描述 给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短.请问,如何最快地判断字符串B中所有字母是否都在字符串A里? 为了简单起见,我们规定输入的字符串只包含大写英文字母,请实 ...

  8. Unicode对象

    什么是Unicode对象呢? 你可以认为unicode对象就是一个Python字符串,它可以处理上百万不同类别的字符——从古老版本的Latin字符到非Latin字符,再到曲折的引用和艰涩的符号. 普通 ...

  9. win7 64 下安装MyGeneration 遇到的问题解决方法

    win7 64 下安装MyGeneration  遇到的问题 ---------------------------MyGeneration 1.3 Setup-------------------- ...

  10. Webpack Waringing Critical dependencies

    报错信息如下: 出错原因先上图: 未注释部分使用了require的同时使用了es6的语法. 官方解释如下: 解决方法就是放开代码中的注释部分,不要使用es6语法