题意:给定a,b两个字符串,让你求将a刷成b所要的最少的次数,刷的时候只能刷连续的一个区间。
思路:先计算出由空串刷成b串的最少次数,因为有相同字符的存在,所以才能尽可能地少刷,设d[i][j]为区间i到j的最少次数,如果第i位和第j位上的字符相同,那么就等价于区间i+1到j的最少话费,因为是由空串转移必然可以先刷i到j,再刷i+1到j-1之间串,如果对应位不相同,那么枚举k,i<k<j,有可能有第k位与第i位相同,然后分成两部分,分别计算更新最小值。
最后,再递推计算一下答案,设ans[i]为a串前i项刷成b串前i项需要的最少次数,如果a[i]==b[i],ans[i]=ans[i-1],依然枚举一下区间去更新,ans[i]=min(ans[i],ans[k]+d[k+1][i])
#include <iostream>
#include <cstdio>
#include <assert.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
using namespace std;
const int INF=1e9+10;
const double EPS = 1e-10;
typedef long long ll;
const ll mod=998244353;
char a[105],b[105];
int d[105][105],ans[105];
int main(){
//freopen("out.txt","w",stdout);
while(scanf("%s%s",a+1,b+1)!=EOF){
int len=strlen(b+1);
for(int i=len;i>=1;i--){
for(int j=i;j<=len;j++){
if(i==j) d[i][j]=1;
else{
if(b[i]==b[j]){
d[i][j]=d[i+1][j];
}else{
d[i][j]=d[i+1][j]+1;
for(int k=i;k<j;k++)
d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);
}
}
}
}
ans[0]=0;
for(int j=1;j<=len;j++){
if(a[j]==b[j])
ans[j]=ans[j-1];
else
ans[j]=ans[j-1]+1;
for(int i=0;i<j;i++)
ans[j]=min(ans[j],ans[i]+d[i+1][j]);
}
printf("%d\n",ans[len] );
}
return 0;
}