String painter
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4905 Accepted Submission(s): 2316
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
Source
Recommend
lcy | We have carefully selected several similar problems for you: 2480 2481 2478 2482 2475
解题思路:这题比较巧妙,需要稍微进行转化,刚开始,令dp[i][j]表示把A区间i - j变成跟B串一样所需要的最小步数,但是,会发现,由于有A的限制,使得这个状态直接计算好像有点麻烦,所以我们进行一次转换,我们令dp[i][j]表示把一个空串变成跟B一样所需要的最小步数,这样就少了许多约束,可以直接转移计算,最后,我们利用这个dp值在A串上再做一次dp就行,令ans[i],前i个字符变成跟B一样所需要的最小步数,然后转移很简单,直接枚举每个分段点就行。
#include <bits/stdc++.h> using namespace std; int inf = 0x3f3f3f3f; const int maxn = 100 + 10; char A[maxn]; char B[maxn]; int dp[maxn][maxn]; int ans[maxn]; void init() { memset(dp, inf, sizeof(dp)); memset(ans, inf, sizeof(ans)); } int main() { while(~scanf("%s%s", A + 1, B + 1)) { init(); int len = strlen(A + 1); for(int i = 1; i <= len; i++) dp[i][i] = 1; for(int i = 2; i <= len; i++) { for(int s = 1; s + i - 1 <= len; s++) { int t = s + i - 1; dp[s][t] = min(dp[s][t], dp[s + 1][t] + 1); for(int k = s + 1; k <= t; k++) { int res; if(k + 1 <= t) res = dp[k + 1][t]; else res = 0; dp[s][t] = min(dp[s][t], dp[s][k] + res); if(B[s] == B[k]) dp[s][t] = min(dp[s][t], dp[s + 1][k] + res); } } } ans[0] = 0; for(int i = 1; i <= len; i++) { if(A[i] == B[i]) ans[i] = ans[i - 1]; else { ans[i] = min(ans[i], ans[i - 1] + 1); for(int j = i - 1; j >= 0; j--) ans[i] = min(ans[i], ans[j] + dp[j + 1][i]); } } printf("%d\n", ans[len]); } return 0; }