题意简述
长度为n(<=300)的01串,你能合并连续一段长度为k(k<=8)的子串。会合并成什么,得到多少分数,由映射表决定。
比如说,映射表是1
2
3
41 10
1 10
0 20
1 30
就代表1
2
3
400->1,得分是10
01->1,得分是10
10->0,得分是20
11->1,得分是30
合理分配合并方案,使得得分最大。
思路框架
区间DP+状压DP
具体思路
观察到wi都是正的,所以我们肯定是把一段区间合并到不能合并才是最优的。
我们每次拿$k$个换一个(前提是有$k$个),所以每次会减少$k-1$个。区间里总共有r-l+1个,所以应该是最后合并出来的长度len=(r-l+1)/(k-1)。前驱状态长度就是len-1个。这个-1千万要注意了,如果(r-l+1)%(k-1)==0,那len就是-1了。所以,当len<=0的时候,记得给他加上一个k-1。
设dp[l][r][s]表示l到r合并成状态s的最大得分。我们枚举断点mid和前驱状态s’,s’=s/2。但是s的最后一位是0/1需要分类讨论。而且满足[l,mid]合并出来的长度为len。解个方程,mid和r关于k-1同余。
我们把l到mid合并成s’,把mid+1到r合并成0/1,来更新dp[l][r][2s’+0/1]的方案。
你以为这就结束了?如果len==k-1,说明原区间的len=k,即,珂以合并完。那么此时我们就是少考虑一个转移,把这种情况特判上。我们枚举最后合并出的状态,计算得分,更新dp。
代码
1 |
|