POJ 3267 The Cow Lexicon (简单DP)
2015-10-05 16:57
405 查看
题目大意
输入一个长度为m的文本串,n个模板。求在文本串中至少去掉几个字母可以完全匹配模板。(2<= m1<= 300, ≤ n ≤ 600,模板串长度 ≤ 25),全部由小写字母组成。分析
dp[i]表示以i结尾的子串至少需要去掉字符数状态转移方程: dp[i] = min(dp[i] , tmp+dp[j]),其中tmp为匹配模板需要去掉的字符数,j是匹配完后的位置。初始化dp[i] = dp[i+1] + 1
对于每个字符c,首先找到模板串中以c开头的模板,然后再逐个匹配,找最佳答案。
代码
#include <iostream> #include <string> #include <cstring> #include <list> using namespace std; const int maxn = 1000; int dp[maxn]; //dp[i]表示从i开始匹配至少要删除的字符数 list<int> lt[26]; string str , s[maxn]; void Init(int n , int m) { memset(dp , 0 , sizeof(dp)); for(int i = 0; i < 26; i++) lt[i].clear(); cin >> str; for(int i = 0; i < n; i++) { cin >> s[i]; lt[s[i][0]-'a'].push_back(i); } } void match(int k , int x , int m) { int len = s[k].length() , i = 0 , j = x , tmp = 0; while(i < len && j < m) { if(str[j] == s[k][i]) {i++; j++;} else {j++; tmp++;} } if(i == len) dp[x] = min(dp[x] , tmp + dp[j]); else dp[x] = min(dp[x] , j - x); } int main() { int m , n; while(cin >> n >> m) { Init(n , m); list<int>::iterator it; // dp[i] = min(dp[i+1] + 1 , tmp + dp[i+len]) for(int i = m-1; i >= 0; i--) { int id = str[i] - 'a'; dp[i] = dp[i+1] + 1; for(it = lt[id].begin(); it != lt[id].end(); it++) match(*it , i , m); } cout << dp[0] << endl; } return 0; }
相关文章推荐
- OpenCV 学习(像素操作 2)
- 第4周 项目4-建立双链表算法库
- OpenCV 学习(像素操作 2)
- 使用Xcode 时候程序莫名其妙Build不过去的可能原因
- LeetCode 068 Text Justification
- GCD的认识和使用
- sk_buff 里的len, data_len, skb_headlen
- cocos代码研究(6)有限时间动作类(FiniteTimeAction)学习笔记
- 二维数组的查找
- 第四周实践项目2-建立单链表算法库
- 第四周 项目6—多项式求和
- apt的引用
- 第四周项目3-单链表的应用逆置
- 第4周 项目3 - 单链表应用(2)
- HDOJ1016.Prime Ring Problem
- 数据挖掘复习 回归2
- 开始学Java,
- 第4周、项目3(3)—单链表应用-递增
- 第3周项目4 顺序表应用问题(1)
- [237]Delete Node in a Linked List