给定一个长度为 (n) 的 (01) 串,每次可以将相邻的 (k) 个字符合并,得到一个新的字符并获得一定的分数。求所能获得的最大分数。
(n leq 300, k leq 8)
Solution
显然长为 (l) 的一段可以合并成长为 ((l-1)mod 7 +1) 的一段
设 (f[l][r][s]) 表示将 ([l,r]) 合并成状态 (s) 的最大分数,考虑转移,枚举哪一部分合成了最后一位,很显然这部分的长度一定是 (7k+1) 的形式
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 305;
int n,k,s[N],c[N],w[N],f[N][N][N];
signed main() {
ios::sync_with_stdio(false);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>s[i];
for(int i=0;i<1<<k;i++) {
cin>>c[i]>>w[i];
}
memset(f,-0x3f,sizeof f);
for(int i=1;i<=n;i++) f[i][i][s[i]]=0;
for(int l=2;l<=n;l++) {
for(int i=1;i+l-1<=n;i++) {
int j=i+l-1;
int len=(l-1)%(k-1)+1;
if(len==1) {
for(int s=0;s<1<<k;s++) {
for(int x=j-1;x>=i;x-=k-1) {
f[i][j][c[s]]=max(f[i][j][c[s]],f[i][x][s>>1]+f[x+1][j][s&1]+w[s]);
}
}
}
else {
for(int s=0;s<1<<len;s++) {
for(int x=j-1;x>=i;x-=k-1) {
f[i][j][s]=max(f[i][j][s],f[i][x][s>>1]+f[x+1][j][s&1]);
}
}
}
}
}
int ans=0;
for(int i=0;i<(1<<k);i++) ans=max(ans,f[1][n][i]);
cout<<ans;
}