HDU2476 String painter(DP)

匿名 (未验证) 提交于 2019-12-02 23:49:02

String painter
给出两个字符串s1,s2。对于每次操作可以将 s1 串中的任意一个子段变成另一个字符。问最少需要多少步操作能将s1串变为s2串。

太妙了这个题,mark一下。

这个题先考虑怎么由空串转化s2,
\(f[i][j]\)表示从空串到s2最少的次数,
则有\(f[i][j]=s[i+1][j]+1\)
\([i+1,j]\)存在一个\(k\),使\(s2[i]==s2[k]\),则\(f[i][j]=min\{f[i+1][k]+f[k+1][j]\}\)
\(k\)为断点,\(i\)\(k\)同时刷。

然后再考虑把s1刷成s2的代价
\(sum[i]\)表示把\(s1[1,i]\)刷成\(s2[1,i]\)的次数
\(s1[i]==s2[i]\)时,可以不刷,显然\(sum[i]=sum[i-1]\)
否则,在区间内找最小次数\(sum[i]=min\{sum[j]+f[j+1][i]\}\)

#include <bits/stdc++.h> using namespace std; const int N = 1e3 + 10;  int n, m;  int f[N][N], sum[N];  char s[N], t[N];  int main() {     while (cin >> s) {         cin >> t;         memset(f, 0, sizeof f);         memset(sum, 0, sizeof sum);         int len = strlen(s);         for (int i = 0; i < len; ++i) f[i][i] = 1;         for (int i = 0; i < len; ++i)              for (int j = i - 1; j >= 0; --j) {                 f[j][i] = f[j + 1][i] + 1;                 for (int k = j + 1; k <= i; ++k) if (t[j] == t[k])                     f[j][i] = min(f[j][i], f[j + 1][k] + f[k + 1][i]);             }         for (int i = 0; i < len; ++i) sum[i] = f[0][i];         if (s[0] == t[0]) sum[0] = 0;         for (int i = 1; i < len; ++i) {             if (s[i] == t[i]) sum[i] = min(sum[i], sum[i - 1]);             else for (int j = 0; j < i; ++j) sum[i] = min(sum[i], sum[j] + f[j + 1][i]);         }         cout << sum[len - 1] << endl;     } }
转载请标明出处:HDU2476 String painter(DP)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!