@xiaoziyao
2020-06-09T20:26:26.000000Z
字数 1192
阅读 1170
解题报告
CF1107E Vasya and Binary String解题报告:
有两道比较相似的题目,可以先做完:CF1132F Clear the String与SP6340 ZUMA - ZUMA。
题意:给定一个长度为的串与得分数组,每次可以从中删除任意子串(子串中所有字符必须相同),可以获得的得分,求删除完的最大得分。
数据范围:。
首先观察题目,可以通过经验得到这道题是区间。
尝试设二维数组,代表删除区间的最大得分,答案便是。
但是这个转移不好写(至少我不会写),而且加上数据范围很小,因此两维应该是不够的。
按照SP6340 ZUMA - ZUMA的经验,我们尝试设三维数组指删除区间前的个与颜色相同的数与区间的最大得分,这样转移就很显然了:
f[l][r][k]=min(f[l][r][k],f[l+1][r][0]+a[k+1]);
f[l][r][k]=min(f[l][r][k],f[l+1][p-1]+f[p][r][k+1]);
然后就是区间的常规做法了。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int maxn=105;
int i,j,k,m,n,p,len;
int a[maxn],f[maxn][maxn][maxn];
string s;
int main(){
scanf("%d",&n);
cin>>s;
s=" "+s;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=2;i<=n;i++)
for(j=1;j<i;j++)
a[i]=max(a[i],a[j]+a[i-j]);
for(len=1;len<=n;len++)
for(i=1;i+len-1<=n;i++){
int j=i+len-1;
for(k=0;k<=n;k++){
f[i][j][k]=max(f[i][j][k],f[i+1][j][0]+a[k+1]);
for(p=i+1;p<=j;p++)
if(s[i]==s[p])
f[i][j][k]=max(f[i][j][k],f[i+1][p-1][0]+f[p][j][k+1]);
}
}
printf("%d\n",f[1][n][0]);
return 0;
}