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
题意:每次将第一个字符串一段连续区间赋予一个值,问从串一变到串二最少多少步。
思路:先求出每个位置都至少被染一次的方案数。dp[i][j]最坏为dp[i][j - 1] + 1;若在i到j - 1之间有k使s[k] == s[j],则dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k][j]),此时意义便是先染k到j,然后处理k + 1到j - 1。
求完dp后再求真正的答案。用ans[i]表示1到i之间需要染多少次,若s[i] == t[i], ans[i] = ans[i - 1];否则枚举1到i - 1之间的k,ans[i] = min(ans[i], ans[k - 1] + dp[k][j])。
#include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <set> #include <map> #include <iomanip> #include <cctype> #include <cassert> #include <bitset> #include <ctime> using namespace std; #define pau system("pause") #define ll long long #define pii pair<int, int> #define pb push_back #define mp make_pair #define clr(a, x) memset(a, x, sizeof(a)) const double pi = acos(-1.0); const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const double EPS = 1e-9; char s[105], t[105]; int dp[105][105], ans[105]; int main() { while (~scanf("%s%s", s + 1, t + 1)) { int L = strlen(s + 1); clr(dp, 0); for (int l = 0; l < L; ++l) { for (int i = 1; i <= L - l; ++i) { int j = i + l; dp[i][j] = dp[i][j - 1] + 1; for (int k = i; k < j; ++k) { if (t[k] == t[j]) dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k][j - 1]); } } } /*for (int i = 1; i <= L; ++i) { for (int j = 1; j <= L; ++j) { cout << dp[i][j] << ' '; } cout << endl; }*/ clr(ans, 63); ans[0] = 0; for (int i = 1; i <= L; ++i) { if (s[i] == t[i]) ans[i] = ans[i - 1]; else { for (int k = 0; k < i; ++k) ans[i] = min(ans[i], ans[k] + dp[k + 1][i]); } } printf("%d ", ans[L]); } return 0; }