题意:
告诉你两个字符串, 问你从第一个字符串刷到第二个字符串最少需要几步? 每次刷操作: 可以把任意一个区间 刷成同一个字母。
思路:
和LightOJ 1422 神似。点击打开链接
这个只是多了一步。真的感觉区间dp 很神奇。
从一个字符串到另一个字符串 不太好操作。
我们先考虑由空字符串刷到 第二个字符串的最少操作。
先令dp[i][j]表示i~j 区间 空字符串刷到 目标串的最少操作。
那么j 个点,可以单独刷 dp[i][j] = dp[i][j-1] + 1;
也可以由前面和它一样的同时刷。 dp[i][j] = min{dp[i][k] + dp[k+1][j-1]} str2[k] == str2[j]
然后在求字符串1 到目标串 的最少操作。
也是一个递推的过程。
令ans[i] 表示把 起始串 前缀[0,,,,i] 刷到目标串的最少操作。
如果str1[i] == str2[i] ans[i] = ans[i-1]
否则 就在前面一个位置 找到最小值 ans[i] = min{ans[j] + dp[j+1][i]}
注意:
如果是记忆话搜索的话, 很难保证 每个区间 都处理到。
直接预处理 10000个dfs 即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100 + 10;
char s[maxn], t[maxn];
int dp[maxn][maxn];
int dfs(int l,int r){
int& ans = dp[l][r];
if (ans != -1) return ans;
if (l > r) return ans = 0;
if (l == r){
return ans = 1;
}
ans = dfs(l,r-1) + 1;
for (int i = l; i < r; ++i){
if (t[i] == t[r]){
ans = min(ans, dfs(i+1, r-1) + dfs(l,i));
}
}
return ans;
}
int ans[maxn];
int main(){
while(~scanf("%s%s",s,t)){
int len = strlen(s);
memset(dp,-1,sizeof dp);
for (int i = 0; i < len; ++i){
for (int j = i; j < len; ++j){
dfs(i,j);
}
}
if (s[0] == t[0]) ans[0] = 0;
else ans[0] = 1;
for (int i = 1; i < len; ++i){
if (s[i] == t[i]){
ans[i] = ans[i-1];
}
else {
ans[i] = dp[0][i];
for (int j = 0; j < i; ++j){
// printf("%d %d %d %d\n", ans[j], dp[j+1][i],j+1,i);
ans[i] = min(ans[i], ans[j] + dp[j+1][i]);
}
}
}
printf("%d\n", ans[len-1]);
}
return 0;
}
String painter
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4251 Accepted Submission(s): 1991
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