/****************************************************** 题意: 给出两个字符串a,b,将a串变为b串; 每次可以将某一个连续区间变成同一个字符,问最少需要操作多少次; 算法: 动态规划(DP) 分析: 第一步: 设dp[i][j]表示从i到j至少要改变多少次; 则状态转移方程为: dp[i][j]=min(dp[i+1][j]+(b[i]==b[j]?0:1),dp[i+1][k]+dp[k+1][j](b[i]==b[k]))。 第二步: 设res[i]表示使长度为i的字符串a到长度为i的字符串b的最小操作的次数; 则有res[i]=min(res[j]+dp[j+1][i],dp[0][i],res[i-1](a[i]==b[i]))。 *******************************************************/ #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=200; char a[N],b[N]; int dp[N][N],res[N]; void solve(int i,int j) { if(dp[i][j]>=0) return; solve(i+1,j); dp[i][j]=dp[i+1][j]+(b[i]==b[j]?0:1); for(int k=i+1; k<=j-1; k++) if(b[i]==b[k]) { solve(i+1,k); solve(k+1,j); if(dp[i+1][k]+dp[k+1][j]<dp[i][j]||dp[i][j]==-1) dp[i][j]=dp[i+1][k]+dp[k+1][j]; } } int main() { //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); while(cin>>a>>b) { int n=strlen(a); for(int i=0; i<n; i++) { res[i]=-1; for(int j=i; j<n; j++) { if(i==j) dp[i][j]=1; else dp[i][j]=-1; } } for(int i=0; i<n; i++) { for(int j=i; j<n; j++) { if(dp[i][j]==-1) solve(i,j); } } if(a[0]==b[0]) res[0]=0; else res[0]=1; for(int i=1; i<n; i++) { res[i]=dp[0][i]; if(a[i]==b[i]) res[i]=res[i-1]; else { for(int j=0; j<=i-1; j++) { if(res[j]+dp[j+1][i]<res[i]) res[i]=res[j]+dp[j+1][i]; } } } cout<<res[n-1]<<endl; } return 0; }