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?
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.
zzzzzfzzzzz abcdefedcba abababababab cdcdcdcdcdcd
6 7
嗯,做了几道题了,感觉有点套路的感觉了。
这个题如果不看第一个串,单纯涂第二个串的的话,不难想到:
dp[i][j]表示i到j的操作的最小值,然后对于i,枚举k的位置,如果i和k的位置上字符相同,dp[i][j] = dp[i+1][k] + dp[k+1][j],然后更新最小值就可以。
但是这里是两个串,从a变到b,这里是用了一个数组ans[i]来表示0~i的一个最小值。
然后直接枚举所有情况取最小值即可。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <time.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int MAXN = 100+7;
int n;
char a[MAXN],b[MAXN];
int dp[MAXN][MAXN];
int ans[MAXN];
int main()
{
while(~scanf("%s%s",a,b))
{
n = strlen(a);
memset(dp,0,sizeof dp);
for(int i = n-1; i >= 0; --i)
for(int j = i; j < n; ++j)
{
dp[i][j] = dp[i+1][j] + 1;//不存在相等的情况
for(int k = i+1; k <= j; ++k)
{
if(b[i] == b[k])dp[i][j] = min(dp[i][j],dp[i+1][k] + dp[k+1][j]);
}
}
//printf("%d\n",dp[0][n-1]);
for(int i = 0; i < n; ++i)
{
ans[i] = dp[0][i];//默认值
if(a[i] == b[i])ans[i] = i?ans[i-1] : 0;//相等就没必要涂
else //不相等,枚举所有情况(类似线性dp)
{
for(int j = 0; j < i; ++j)ans[i] = min(ans[i],ans[j] + dp[j+1][i]);
}
}
printf("%d\n",ans[n-1]);
}
return 0;
}