题意:
有a,b两字符串,现在你有一个刷子,每次可以任选一个区间,使这个区间变成你想要的字符,现在让你将a变成b,问最少刷多少次
题解:
考虑区间dp[i][j],表示从第i到第j最少需要刷的次数。这里要先算从空串到b的dp,然后根据这个来推a串到b串的最小次数。
因为如果a的整个区间需要重新构造,这个区间就相当于空串。状态转移方程具体看代码
1 #include<cstdio> 2 #include<cstring> 3 #define F(i,a,b) for(int i=a;i<=b;i++) 4 5 const int N=107; 6 char a[N],b[N]; 7 int dp[N][N],ans[N]; 8 9 inline void up(int &a,int b){if(a>b)a=b;} 10 11 int main() 12 { 13 while(~scanf("%s%s",a+1,b+1)) 14 { 15 int n=strlen(a+1); 16 memset(dp,0,sizeof(dp)); 17 F(i,1,n)dp[i][i]=1; 18 F(l,1,n-1)F(i,1,n-l) 19 { 20 int j=i+l; 21 dp[i][j]=dp[i+1][j]+1; 22 F(k,i+1,j)if(b[i]==b[k])up(dp[i][j],dp[i+1][k]+dp[k+1][j]); 23 } 24 F(i,1,n)ans[i]=dp[1][i]; 25 F(i,1,n)if(a[i]==b[i])ans[i]=(i==1?0:ans[i-1]); 26 else F(j,1,i-1)up(ans[i],ans[j]+dp[j+1][i]); 27 printf("%d\n",ans[n]); 28 } 29 return 0; 30 }
时间: 2024-10-13 05:20:23