#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int dp[105][105];
int ans[200];
int main(void)
{
string s1 , s2;
while(cin>>s1)
{
memset(ans,0,sizeof(ans));
memset(dp,0,sizeof(dp));
int len = s1.length();
cin>>s2;
//从""空串 -> “abcd”目标串 -> 4
for(int j = 0 ; j < len; j ++)
{
for(int i = j ; i >= 0 ; i --)
{
dp[i][j] = dp[i+1][j] + 1;
//printf("1 dp[%d][%d] = %d\n",i,j,dp[i][j]);
for(int k = i + 1 ; k <= j ; k ++)
{
if(s2[i] == s2[k])//开始进行区间DP
{
dp[i][j] = min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
//printf("2 dp[%d][%d] = %d\n",i,j,dp[i][j]);
}
}
}
}
/*********************************************
从“ ”空串 -> “abcd”目标串 -> 4 , “abbb”给定串 -> "abcd"目标串 -> 2,
对比两个步骤,因为空串到目标串,考虑的是完全不相同串(空串)到目标串的过程(上一个步骤虽然优化了但是对于题目来说并不是最优,
因为有可能给定串和目标串有重复部分,所以需要进一步优化).
所以有以下步骤.
**********************************************/
for(int i = 0 ; i < len ; i ++)
ans[i] = dp[0][i];
for(int i = 0 ; i < len ; i ++)
{
if(s1[i] != s2[i])
{
for(int j = 0 ; j < i ; j ++)
{
ans[i] = min(ans[i] , ans[j] + dp[j+1][i]);
//printf("ans[%d] = %d\n",i,ans[i]);
}
}
else
ans[i] = ans[i-1];
}
cout<<ans[len - 1]<<endl;
//cout<<dp[0][len-1]<<endl;
}
return 0;
}
对于第一个步骤不太理解的同学可以参考这篇博客:https://www.dreamwings.cn/hdu2476/4074.html