/* dp[l][r]表示将任意串的[l,r]刷成s2样子的最小代价 ans[i]表示将s1的前i位刷成s2的代价 按照区间dp的常用做法,dp[l][r]的状态由dp[l][k],dp[k+1][r]决定 若s2[l]==s2[k],那么在刷k的时候也能刷到l,dp[l][r]=min(dp[l][r],dp[l+1][k]+dp[k+1][r]) 但是有可能所有的s[k]!=s[l],即s2[l]要被单独刷一次,那么dp[l][r]要被赋初值dp[l][r]=1+dp[l+1][r] 第二步计算ans数组,若s1[i]==s2[i],那么第i位就不用刷,即ans[i]=ans[i-1] 否则ans[i]=min(ans[i],ans[k]+dp[k+1][i]); */ #include<bits/stdc++.h> using namespace std; char s1[200],s2[200]; int dp[200][200],ans[200],n; int main(){ while(scanf("%s%s",s1,s2)==2){ n=strlen(s1); memset(dp,0,sizeof dp); for(int r=0;r<n;r++)//右边界 for(int l=r;l>=0;l--){//左边界依次拓展 dp[l][r]=dp[l+1][r]+1; for(int k=l+1;k<=r;k++) if(s2[l]==s2[k])//只要将刷左子区间和刷右子区间的值合并即可 dp[l][r]=min(dp[l][r],dp[l+1][k]+dp[k+1][r]); } for(int i=0;i<n;i++) ans[i]=dp[0][i]; for(int i=0;i<n;i++) if(s1[i]==s2[i])ans[i]=ans[i-1]; else { for(int j=0;j<i;j++) ans[i]=min(ans[i],ans[j]+dp[j+1][i]); } printf("%d ",ans[n-1]); } }