SDUTOJ. LCS问题.(DP)
来源:互联网 发布:java字符串包含字符串 编辑:程序博客网 时间:2024/06/06 15:48
题目链接:
SDUTOJ1008
题目大意:
求N个串的最长最长公共子串。重点是N个,之前2个的话会求,N个变了下数量居然不会了……
解题过程:
- 首先想到的是先求两个的LCS,LCS再与下一个串比较,直到比较完所有的串,显然这样是不对的。
- 因为题目是N个串,之前求2个串直接嵌套循环就好了,现在N个的话就一脸懵逼了,于是想嵌套10个循环来着,最后放弃了。
- 最后看了巨巨的博客(巨巨博客),才恍然大悟,说好的dp居然用dfs(然后下面的dp题也有好多就是dfs解的),不过把下标映射成一维数组也是学到了。 -
解题分析:
- 首先题目说到了长度乘积不超过30000,也就差不多示意要把N个数组的状态映射成一维数组储存。
- 下面是关于如何映射和状态方程(可耻的盗了图):
AC代码:
#include<iostream>#include<cstring>#include<cstdio>using namespace std;int n;string data[112];int dp[31234], len[112];int get_index(){ int result=len[0]-1; for (int i = 1; i < n; i++) { result = result * data[i].size() + len[i]-1; } return result;}int lcs(){ for (int i = 0; i < n; i++) { if (len[i] == 0) return 0; } int index = get_index(); if (dp[index] >= 0) { return dp[index]; } int flag = 1; for (int i = 1; i < n; i++) { if (data[i][len[i]-1] != data[0][len[0]-1]) { flag = 0; break; } } int result; if (flag) { for (int i = 0; i < n; i++) { len[i]--; } result = lcs() + 1; for(int i = 0; i < n; i++) { len[i]++; } } else { result = 0; for (int i = 0; i < n; i++) { len[i]--; result = max(lcs(), result); len[i]++; } } dp[index] = result; return result;}int main(){ int T; cin >> T; while(T--) { for (int i = 0; i < 110; i++) { data[i].clear(); } memset(len, 0, sizeof(len)); memset(dp, -1, sizeof(dp)); cin >> n; for (int i = 0;i < n; i++) { cin >> data[i]; len[i] = data[i].size(); } cout << lcs() << endl; }}
依次取LCS方法(错误):
既然写了就放出了玩玩好了,谁知道什么时候能用到呢。
#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<cstdio>using namespace std;string max_len(string a, string b){ if (a.size() > b.size()) return a; else return b;}string find_lcs(string a, string b){ string data[112][112]; int i, j; for (i = 0; i < 112; i++) { for (j = 0; j < 112; j++) { data[i][j].clear(); } } for (i = 1; i <= a.size(); i++) { for (j = 1; j <= b.size(); j++) { if (a[i-1] == b[j-1]) { data[i][j] = data[i-1][j-1] + a[i-1]; } else { data[i][j] = max_len(data[i-1][j], data[i][j-1]); } } } return data[a.size()][b.size()];}int main(){ int T; cin >> T; while (T--) { int n; string str, result; cin >> n; cin >> result; n--; while (n--) { cin >> str; result = find_lcs(result, str); } cout << result.size() << endl; }}
0 0
- SDUTOJ. LCS问题.(DP)
- SDUTOJ 2080 最长公共子序列问题(LCS)
- 【DP,lcs问题】整理队形
- DP---LCS 最长公共子序列问题
- SDUTOJ-1650-dp
- DP:LCS
- LCS-DP
- DP--LCS
- 约瑟夫问题 sdutoj 1197
- 约瑟夫问题 sdutoj 1197
- POJ1458 Common Subsequence LCS问题入门题[DP]
- DP最长公共子序列LCS问题笔记
- LCS 最长公共子序列(DP经典问题)
- poj 2264 Advanced Fruits dp解LCS的对偶问题
- 最长公共子序列(LCS问题)的DP解法
- 基于DP的LCS(最长公共子序列)问题
- hdoj1080 Human Gene Functions(DP解决LCS问题!)
- LCS问题
- leetcode_137. Single Number II 只出现一次的数字 II 偏离了题目考点,主要是为了写下java
- Android MediaProjection截屏与录屏(surfaceview截图)
- linux ./configure 选项参数
- 链式存储中在第i个位置插入或删除的时间复杂度
- Android OpenGL 坐标系 <2>
- SDUTOJ. LCS问题.(DP)
- 数据挖掘概念与技术——读书笔记(7)
- javascript定时器+DOM查看视口以及元素尺寸和位置
- SMO优化算法
- MySQL5.7 多线程复制,配置和测试结果
- 自定义EditText清除
- 编译器的工作过程
- Cordova拨号获取通话时长
- 9.6 MATLAB while循环结构