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
题意:
给出两个字符串,现,可以对第一个字符串进行修改操作——将某段连续区间全部修改为同一个字符。问由第一个字符串 A A 变成第二个串,至少需要做几次操作?
分析:
由 A A 变成,对于当前第 i i 位,有以下转移:
- 如果 ,那么第
i
i
位可以不修改,即
- 否则,在
[1,k]
[
1
,
k
]
的基础上,修改
[k+1,i]
[
k
+
1
,
i
]
,即
f[i]=f[k]+change(k+1,i) f [ i ] = f [ k ] + c h a n g e ( k + 1 , i )
那么,现在的问题就是求解 change(k+1,i) c h a n g e ( k + 1 , i ) ,由于对于任意一个 k k 都需要求解,问题就相当于,将一个空串变成第二个字符串的最少操作次数
我们可以定义状态: 为 修改区间 [i,j] [ i , j ] 变成 Bi,Bi+1,...,Bj B i , B i + 1 , . . . , B j 需要的最少操作次数
对于区间 [i,j] [ i , j ] , dp[i][j] d p [ i ] [ j ] 转移如下:
- 在区间
[i+1,j]
[
i
+
1
,
j
]
的基础上,仅仅修改
i
i
位置的字符,则有
- 分成两段区间
[i,k]
[
i
,
k
]
和
[k+1,j]
[
k
+
1
,
j
]
进行修改,则有
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]) d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , d p [ i ] [ k ] + d p [ k + 1 ] [ j ] )
则可以将转移方程 f[i]=f[k]+change(k+1,i) f [ i ] = f [ k ] + c h a n g e ( k + 1 , i ) 修改为 f[i]=f[k]+dp[k+1][i] f [ i ] = f [ k ] + d p [ 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; }
- 在区间
[i+1,j]
[
i
+
1
,
j
]
的基础上,仅仅修改
i
i
位置的字符,则有
- 否则,在
[1,k]
[
1
,
k
]
的基础上,修改
[k+1,i]
[
k
+
1
,
i
]
,即