[关闭]
@xiaoziyao 2020-06-09T20:26:26.000000Z 字数 1192 阅读 1170

CF1107E Vasya and Binary String解题报告

解题报告


CF1107E Vasya and Binary String解题报告:

更好的阅读体验

前言

有两道比较相似的题目,可以先做完:CF1132F Clear the StringSP6340 ZUMA - ZUMA

题意

题意:给定一个长度为与得分数组,每次可以从中删除任意子串(子串中所有字符必须相同),可以获得的得分,求删除完的最大得分。

数据范围:

分析

首先观察题目,可以通过经验得到这道题是区间

尝试设二维数组,代表删除区间的最大得分,答案便是

但是这个转移不好写(至少我不会写),而且加上数据范围很小,因此两维应该是不够的。

按照SP6340 ZUMA - ZUMA的经验,我们尝试设三维数组指删除区间前的个与颜色相同的数与区间的最大得分,这样转移就很显然了:

  1. 可以将前面附加的数与第个数一起删除,就可以从转移来,也就是f[l][r][k]=min(f[l][r][k],f[l+1][r][0]+a[k+1]);
  2. 枚举所有与区间第一个数相同的断点,这样可以先删除区间,然后删除前面附加的数个数区间,也就是f[l][r][k]=min(f[l][r][k],f[l+1][p-1]+f[p][r][k+1]);

然后就是区间的常规做法了。

代码

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<iostream>
  4. using namespace std;
  5. const int maxn=105;
  6. int i,j,k,m,n,p,len;
  7. int a[maxn],f[maxn][maxn][maxn];
  8. string s;
  9. int main(){
  10. scanf("%d",&n);
  11. cin>>s;
  12. s=" "+s;
  13. for(i=1;i<=n;i++)
  14. scanf("%d",&a[i]);
  15. for(i=2;i<=n;i++)
  16. for(j=1;j<i;j++)
  17. a[i]=max(a[i],a[j]+a[i-j]);
  18. for(len=1;len<=n;len++)
  19. for(i=1;i+len-1<=n;i++){
  20. int j=i+len-1;
  21. for(k=0;k<=n;k++){
  22. f[i][j][k]=max(f[i][j][k],f[i+1][j][0]+a[k+1]);
  23. for(p=i+1;p<=j;p++)
  24. if(s[i]==s[p])
  25. f[i][j][k]=max(f[i][j][k],f[i+1][p-1][0]+f[p][j][k+1]);
  26. }
  27. }
  28. printf("%d\n",f[1][n][0]);
  29. return 0;
  30. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注