LCS+路径还原
来源:互联网 发布:网络电话拨号软件 编辑:程序博客网 时间:2024/06/07 01:29
51nod动态规划教程
最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。
输入
第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)
输出
输出最长的子序列,如果有多个,随意输出1个。
输入示例
abcicba
abdkscab
输出示例
abca
思路:
刚开始按照LIS的nlgn解法思路记录路径,发现错多了。LCS更新的方式就是分两种情况(两个字符相等和不相等)和三个方向(左,上,左上)取最大值,dp[i + 1][j + 1]表示的是在A串前i位和B串前j位的LCS(可能不止一个序列,但最大值唯一),由于序列不唯一,路径还原就需要找dp增加的时候来自的两种情况。字符相等的情况才是真正的路径,不相等时只是为了更新这个dp值(为下一个相等时做准备),这样问题就easy了,用二维数组记录dp值增加来自的三个方向,开始逆着搜索,当出现字符相等的情况输出这个字符;
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define max_n 1010using namespace std;int dp[max_n][max_n], pre[max_n][max_n];char A[max_n], B[max_n], C[max_n];void dfs(int x, int y) { //找来自的方向 if(x == 0 || y == 0) return; else if(pre[x][y] == 1) { dfs(x - 1, y - 1); printf("%c", A[x - 1]); } else if(pre[x][y] == 2) { dfs(x - 1, y); } else dfs(x, y - 1);}int main() { memset(pre, 0, sizeof(pre)); //记录dp增加 来自的方向 memset(dp, 0, sizeof(dp)); gets(A); gets(B); int len1 = strlen(A); int len2 = strlen(B); for(int i = 0; i < len1; i++) { for(int j = 0; j < len2; j++) { if(A[i] == B[j]) { dp[i + 1][j + 1] = dp[i][j] + 1; pre[i + 1][j + 1] = 1; //来自左上方,下标是字符串下标+1 } else { if(dp[i][j + 1] > dp[i + 1][j]) { dp[i + 1][j + 1] = dp[i][j + 1]; pre[i + 1][j + 1] = 2; //来自j + 1; } else { dp[i + 1][j + 1] = dp[i + 1][j]; pre[i + 1][j + 1] = 3; //来自i + 1 } } } } dfs(len1, len2); return 0;}
阅读全文
1 0
- LCS+路径还原
- 路径还原
- 路径还原
- 路径还原
- poj2250-打印单一LCS路径。
- 最短路径路径还原
- 最短路路径还原
- 弗洛伊德算法 路径还原
- dijkstra优化+路径还原
- LightOJ 1110 An Easy LCS LCS路径输出
- lightoj 1110 - An Easy LCS (LCS输出路径)
- 还原数据库到指定路径
- 最短路问题路径还原
- USACO2014FebruaryGold Roadblock Dijkstra+路径还原
- poj 3984 bfs+路径还原
- POJ 2250--Compromise(LCS以及路径记录)
- poj 2250 (LCS 需打印路径)
- poj2250 Compromise dp lcs 记录路径
- Charles抓包软件简介
- php static
- mysql
- oracle实用知识(五)
- http://dl-ssl.google.com/android上不去解决方案
- LCS+路径还原
- bzoj 5241. 【GDOI2018模拟8.8】苹果和雪梨 贪心
- 安卓实训笔记第二天
- 七、基础教程-坐标轴(Axis)
- Js中JSON对象
- quartus || 怎样调用PLL 核
- 8月8日训练笔记
- 【MVC】传值大全参考
- Configuration--mappers(三-8)