poj 1934 Trip 多个最长公共子序列
来源:互联网 发布:cg绘画软件 编辑:程序博客网 时间:2024/05/01 00:28
题目要你按字典序输出两个字符串的多个最长公共子序列
转自http://blog.csdn.net/tsaid/article/details/6726698
思路:
先用动态规划求两个字符串的最长公共子序列的保存在dp[i][j];dp[i][j]表示s1字符串1到i和s2字符串1到j的最长公共子序列的长度
然后用两个变量last1[i][j],last2[i][j]来分别保存字符j(a的序号为0,b的序号为1,.....z的序号为25)在字符串1-i中出现的最大标号,要是字符j没有出现,则last[i][j]= 0;
然后从两个字符串的长度len1和len2开始枚举a---z字符,比如开始 t1 = last1[len1][0], t2 = last2[len2][0]表示a在s1字符串1---len1的最大下标为t1,在s2字符串1--len2的最大下标为t2,那么若dp[t1][t2]的值为s1和s2的最大公共子序列长度cnt则表示这个字符符合,保存起来,否则枚举下一个字符b。若满足情况的话,在继续在t1-1和 t2 - 1符合最大公共子序列为cnt - 1的字符串保存,如此循环,知道到达最长公共子序列为0时结束。把保存的字符串放入set集合里面,让它按字典序排序。
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <set>using namespace std;int const maxn = 100;char s1[maxn], s2[maxn], tmp[maxn];int dp[maxn][maxn], last1[100][30], last2[100][30], len1, len2, cnt;set<string> collection;void LCA();void handle(char s[], int len, int last[][30]);void find(int index1, int index2, int len);int main(){ scanf("%s %s", &s1[1], &s2[1]); LCA(); handle(s1, len1, last1); handle(s2, len2, last2); cnt = dp[len1][len2]; tmp[cnt+1] = '\0'; find(len1, len2, cnt); for(set<string>::iterator iter = collection.begin(); iter != collection.end(); iter++) printf("%s\n", iter->c_str()); return 0;}void LCA(){ int i, j; for(i = 1; s1[i] != '\0'; i++) { for(j = 1; s2[j] != '\0'; j++) { if(s1[i] == s2[j]) dp[i][j] = dp[i-1][j-1] + 1; else if(dp[i-1][j] >= dp[i][j-1]) dp[i][j] = dp[i-1][j]; else dp[i][j] = dp[i][j-1]; } } len1 = i - 1; len2 = j - 1;}void handle(char s[], int len, int last[][30]){ for(int i = 0; i < 26; i++) { char c = 'a' + i; for(int j = 1; j <= len; j++) { int k; for(k = j; k >= 1; k--) { if(c == s[k]) { last[j][i] = k; break; } } if(k == 0) last[j][i] = 0; } }}void find(int index1, int index2, int len){ if(len <= 0) { collection.insert(&tmp[1]); return; } if(index1 > 0 && index2 > 0) { for(int i = 0; i < 26; i++) { int t1 = last1[index1][i]; int t2 = last2[index2][i]; if(dp[t1][t2] == len) { tmp[len] = 'a' + i; find(t1 - 1, t2 - 1, len - 1); } } }}
- poj 1934 Trip 多个最长公共子序列
- poj 1934 Trip 多个最长公共子序列
- poj 1934 Trip 所有最长公共子序列 仍然WA
- poj 1934 Trip 题解(加强版最长公共子序列)
- POJ 1458 最长公共子序列
- POJ 1458 最长公共子序列
- 最长公共子序列 POJ 2250
- POJ 1458 最长公共子序列
- poj 1458 最长公共子序列
- poj 2250 最长公共子序列
- poj 1458 最长公共子序列
- poj Common Subsequence 最长公共子序列
- POJ 3080 多个串最长公共子序列
- POJ 2127 最长公共上升子序列
- POJ 1156 Palindrome (最长公共子序列)
- poj 1458 最长公共子序列
- POJ 1458最长公共子序列(DP)
- poj 1159 Palindrome(最长公共子序列)
- 对互斥体 信号量 事件和临界区的一些小看法
- Linux学习经典书籍
- VMWare网络设置的3中方式
- 开源镜像站
- jQuery插件的制作之方法的参数
- poj 1934 Trip 多个最长公共子序列
- uva 11181 Probability|Given
- 第二周小结
- 二分匹配之匈牙利算法
- poj 1731 orders
- 开源界面库
- 例题3-1
- nutch-2.0源码解读——简介
- Android手机访问web服务器(post请求)