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.
Output
A single line contains one integer representing the answer.
Sample Input
zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd
Sample Output
6
7
题意:
给出两个字符串,现,可以对第一个字符串进行修改操作——将某段连续区间全部修改为同一个字符。问由第一个字符串AA变成第二个串,至少需要做几次操作?
分析:
由AA变成,对于当前第ii位,有以下转移:
- 如果 ,那么第 ii 位可以不修改,即
- 否则,在[1,k][1,k]的基础上,修改[k+1,i][k+1,i],即 f[i]=f[k]+change(k+1,i)f[i]=f[k]+change(k+1,i)
那么,现在的问题就是求解 change(k+1,i)change(k+1,i),由于对于任意一个 kk 都需要求解,问题就相当于,将一个空串变成第二个字符串的最少操作次数
我们可以定义状态: 为 修改区间[i,j][i,j]变成Bi,Bi+1,...,BjBi,Bi+1,...,Bj需要的最少操作次数
对于区间 [i,j][i,j] , dp[i][j]dp[i][j]转移如下:
- 在区间 [i+1,j][i+1,j] 的基础上,仅仅修改 ii 位置的字符,则有
- 分成两段区间 [i,k][i,k] 和 [k+1,j][k+1,j] 进行修改,则有dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j])dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j])
则可以将转移方程f[i]=f[k]+change(k+1,i)f[i]=f[k]+change(k+1,i) 修改为 f[i]=f[k]+dp[k+1][i]f[i]=f[k]+dp[k+1][i]
最终答案为 f[n]f[n]
代码:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<algorithm> #include<time.h> #include<iostream> #include<vector> #include<stack> #include<queue> #include<set> #include<map> using namespace std; #define bll long long const int maxn = 110; char s[maxn],t[maxn]; int dp[maxn][maxn],ans[maxn]; int main() { while (scanf("%s %s",s+1,t+1)!=EOF) { int n = strlen(s+1); memset(dp,0,sizeof(dp)); for (int i=1;i<=n;i++) for (int j=i;j<=n;j++) dp[i][j] = j-i+1; for (int i=n;i>0;i--) { for (int j=i+1;j<=n;j++) { int tmp = (t[i]==t[j])? 0 : 1; dp[i][j] = min(dp[i][j],dp[i+1][j]+tmp); for (int k=i+1;k<j;k++) dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]); } } memset(ans,0,sizeof(ans)); for (int i=1;i<=n;i++) { ans[i] = (s[i]==t[i])? ans[i-1] : ans[i-1]+1; for (int j=0;j<i;j++) ans[i] = min(ans[i],ans[j]+dp[j+1][i]); } printf("%d\n",ans[n]); } return 0; }
- 否则,在[1,k][1,k]的基础上,修改[k+1,i][k+1,i],即