http://acm.hdu.edu.cn/showproblem.php?pid=2476
先是考虑将所有与目标字符串不相同的刷成目标串:
dp[i][j]表示刷i-j区间,
初始条件:dp[i][j]=dp[i+1][j]+1;
对于k=(i+1...j )如果str[k]==str[i],则dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]),,因为刷i的时候可以与k同时刷。
上面是对初始串与目标串完全不同的情况,
如果有部分的不同:
ans[i]表示将str1[0...i]刷成str2[0...i]的最小步数,
if str1[i]==str2[i] 则ans[i]=ans[i-1];
else
ans[i]=min(ans[i],ans[j]+dp[j+1][i]) j<i;
代码:
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
char str1[150];
char str2[150];
int dp[150][150];
int ans[150];
int main()
{
while(scanf("%s%s",str1,str2)!=EOF)
{
int n=strlen(str1);
int i,j,k;
int li;
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
dp[i][j]=j-i+1;
}
for(li=0;li<n;li++)
{
for(i=0;i<n&&i+li<n;i++)
{
j=i+li;
dp[i][j]=dp[i+1][j]+1;
for(k=i+1;k<=j;k++)
{
if(str2[k]==str2[i])
dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
}
}
}
if(str1[0]==str2[0])
ans[0]=0;
else
ans[0]=1;
for(i=1;i<n;i++)
{
ans[i]=dp[0][i];
if(str1[i]==str2[i])
ans[i]=ans[i-1];
else
{
int k;
for(k=0;k<i;k++)
ans[i]=min(ans[i],ans[k]+dp[k+1][i]);
}
}
printf("%d\n",ans[n-1]);
}
return 0;
}