解题思路:dp[i][j]表示i位置到j位置变换后所需最小次数。因为我们一开始初始dp[i][j]为dp[i+1][j]+1,那么我们只需要考虑i与I+1直接是否有与i相同的字符,那么状态转移为dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]).之后还要再对dp[1][1~n]进行优化。


代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include<algorithm>>
using namespace std;
#define inf 0x3f3f3f3f
const int mx = 1e2+10;
int n,m,dp[mx][mx],ans[mx];
char str[mx],stc[mx];
int main(){
    while(~scanf("%s%s",str+1,stc+1)){
        int len = strlen(str+1);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=len;i++) dp[i][i] = 1;
        for(int t=1;t<=len;t++){
            for(int i=1;i<=len;i++){
                int j = i+t;
                if(j>len) break;
                dp[i][j] = dp[i+1][j]+1;
                for(int k=i+1;k<=j;k++)
                if(stc[i]==stc[k]) dp[i][j] = min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
            }
        }
        for(int i=1;i<=len;i++) ans[i] = dp[1][i];
        for(int i=1;i<=len;i++){
            if(str[i]==stc[i]) ans[i] = ans[i-1];
            else{
                for(int j=1;j<i;j++)
                ans[i] = min(ans[i],ans[j]+dp[j+1][i]);
            }
        }
        printf("%d\n",ans[len]);
    }
    return 0;
}