srm 306 div2 1000 (字符串dp,进阶)
来源:互联网 发布:电脑nfc读写软件 编辑:程序博客网 时间:2024/05/21 19:22
题意:
有一个原串s和一个目标串t。
向s插入一些串,这些被插入的串被称为block,使得s与t相同。
求最少插入多少block达到目标。
思路:
O(n3)的做法:设i,j分别是s,t中的下标。那么方程描述为:把从i开始的s的字串变成从j开始的t的字串最少插入的block。
决策有两种,分别对应s[i]=s[j]和s[i]!=s[j]:
1)相等:转移到dp(i+1, j+1)
2)不等:找一个k > j,转移到dp(i, k) + 1(t[j…k]变成block)
通过加一维表示当前是匹配是否连续,可以把时间复杂度降为O(n2)
const int inf = INT_MAX / 2;int f[1005][1005][2];class BlockDistance{ public: // b = 1,连续 // b = 0,不连续 int dp(string &s, string &t, int i, int j, int b) { if (i >= s.length() && j >= t.length()) return 0; if (i >= s.length()) return 1; if (j >= t.length()) return inf; if (f[i][j][b] != -1) return f[i][j][b]; int ret = inf; if (s[i] == t[j]) ret = min (ret, dp(s, t, i+1, j+1, 1)); ret = min (ret, dp(s, t, i, j+1, 0) + b); return f[i][j][b] = ret; } int minDist(vector <string> oldText, vector <string> newText) { string a, b; for (int i=0;i<oldText.size();++i) a += oldText[i]; for (int i=0;i<newText.size();++i) b += newText[i]; memset(f, -1, sizeof(f)); int ans = dp (a, b, 0, 0, 1); return ans == inf ? -1 : ans; }};
0 0
- srm 306 div2 1000 (字符串dp,进阶)
- srm 304 div2 1000(环形DP进阶,几何)
- srm 655 div2 1000(DP进阶,枚举状态)
- srm 300 div2 1000(贪心进阶)
- srm 653 div2 1000(dp)
- srm 656 div2 1000(dp+组合)
- srm 301 div2 1000 (经典dp, 括号匹配)
- srm 302 div2 1000(简单题,bfs,dp)
- topcoder SRM 654 DIV2 1000 SuccessiveSubtraction2 题解(dp)
- srm 308 div2 1000(DP, 离散背包+连续背包)
- SRM 649 div2 500(dp)
- srm 654 div2 1000 (DP,最大连续和拓展, 有亮点)
- TopCoder SRM 648 Div2 Problem 1000 - ABC (DP)
- TopCoder SRM 663 Div2 Problem 1000 - CheeseRolling (状压dp)
- TopCoder SRM 672 Div2 Problem 1000 - Tdetectived2 (状压dp)
- Topcoder SRM 663 Div2 Hard: CheeseRolling(状压DP)
- srm 307 div2 1000(数论,枚举)
- SRM 678 div2 (1000题待补)
- android 混淆时忽略第三方jar包的
- Linux系统fork执行过程
- 拆分字符串 StringToken
- js克隆对象或数组
- ViewController的生命周期分析和使用
- srm 306 div2 1000 (字符串dp,进阶)
- android虚拟机快速启动
- C#控件命名规范
- JAVA – 虚函数、抽象函数、抽象类、接口
- 预留端口避免占用
- 数据结构之散列表
- 源代码计算器
- 运算符重载
- 黑马程序员---OC基础知识⑥