正题
题目链接:https://www.luogu.com.cn/problem/P4170
题目大意
给出长度为nnn的串目标串,每次可以在一连续的区间覆盖同种字符,求最少覆盖次数。
解题思路
我们分情况考虑,用fi,jf_{i,j}fi,j表示从i∼ji\sim ji∼j都涂好需要的最少次数,
- 若i==ji==ji==j,那么显然有fi,j=1f_{i,j}=1fi,j=1
- 若i!=ji!=ji!=j且si==sjs_i==s_jsi==sj那么最开始一段这个覆盖即可,所以有fi,j=min{fi+1,j,fi,j−1}f_{i,j}=min\{f_{i+1,j},f_{i,j-1}\}fi,j=min{fi+1,j,fi,j−1}
- 若i!=ji!=ji!=j且si!=sjs_i!=s_jsi!=sj那么这两点之间毫无关系,我们枚举一个中间点kkk来进行dpdpdpfi,j=min{fi,k+fk+1,j}f_{i,j}=min\{f_{i,k}+f_{k+1,j}\}fi,j=min{fi,k+fk+1,j}
然后O(n3)O(n^3)O(n3)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=55;
int n,f[N][N];
char s[N];
int main()
{scanf("%s",s+1);n=strlen(s+1);memset(f,0x3f,sizeof(f));for(int i=1;i<=n;i++)f[i][i]=1;for(int l=1;l<n;l++)for(int i=1;i+l<=n;i++){int j=i+l;if(s[i]==s[j])f[i][j]=min(f[i][j-1],f[i+1][j]);elsefor(int k=i;k<j;k++)f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);}printf("%d",f[1][n]);
}