Problem Description
There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string painter. With the help of the painter, you can change a segment of characters of a string to any other character you want. That is, after using the painter, the segment is made up of only one kind of character. Now your task is to change A to B using string painter. What’s the minimum number of operations?
Input
Input contains multiple cases. Each case consists of two lines:
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.
Output
A single line contains one integer representing the answer.
Sample Input
zzzzzfzzzzz abcdefedcba abababababab cdcdcdcdcdcd
Sample Output
6 7
标准区间dp,不过考虑这题要分两步,首先考虑每个字母全都不相同的情况要改多少,这种情况较好想,拿dp[i][j]来说的话如何求呢?显然 dp[i][j]要由dp[i][k]+dp[k+1][j]决定,如果s2[i]==s2[k]则dp[i][j]=dp[i+1][k]+dp[k+1][j],但有一种情况要考虑的是如果所有s2[i]!=s2[k],怎么办?!所以dp[i][j]的初值不能赋值为正无穷,区间dp很常见的方法就是以区间i到j为对象,取i为特殊点作为参照,所以dp[i][j]最常见复制方式(就是最大值(题目要求的是最小值所以我们考虑最大值))就是dp[i][j]=dp[i+1][j]+1;这样代码实现起来应该没问题了,递推和记忆化搜索都行。第二步在开个数组记录前i个字母要改变的最小值,那么怎样最小呢?看代码就懂了!
#include<iostream>
#include<algorithm>
#include <cstdio>
#include <cmath>
#include<cstring>
using namespace std;
int a[105],dp[105][105];char s1[105],s2[105];
int solve(int i,int j)
{
if(dp[i][j]!=-1)return dp[i][j];
if(i>j)return dp[i][j]=0;
if(i==j)return dp[i][j]=1;
dp[i][j]=solve(i+1,j)+1;
for(int k=i+1;k<=j;k++)
if(s2[k]==s2[i])
dp[i][j]=min(solve(i+1,k)+solve(k+1,j),dp[i][j]);
return dp[i][j];
}
int main ()
{
while(cin>>s1>>s2)
{
memset(dp,-1,sizeof(dp));memset(a,0,sizeof(a));
int l=strlen(s1);
for(int i=0;i<l;i++)
{
for(int j=i;j<l;j++)
int t=solve(i,j);
}
// cout<<dp[0][0]<<endl;
for(int i=0;i<l;i++)
{
a[i]=dp[0][i];
if(s1[i]==s2[i])
{
if(i==0)
a[i]=0;
else
a[i]=a[i-1];
}
else
{
for(int j=0;j<i;j++)
a[i]=min(a[i],a[j]+dp[j+1][i]);
}
}
printf("%d\n",a[l-1]);
}
return 0;
}