最长公共上升子序列
来源:互联网 发布:女网球运动服知乎 编辑:程序博客网 时间:2024/05/22 23:44
比较直观的做法(O(n^4))
if xi != yj dp[i][j] = 0else dp[i][j] = max(dp[ii][ij]) ( 0 <= ii < i, 0 <= ij < j, dp[ii][ij] != 0 && x[ii] < x[i]) + 1
O(n^3)的算法
if xi != yj dp[i][j] = dp[i-1][j]else dp[i][j] = max(dp[i-1][k])(0 < k < j && y[k] < y[j]) + 1
反证:设s, s[0...sn]为x[0...m-1]和y[0...k]上的, 以x[k]为结束的一个LICS, 并且sn > zn-1.那么,s[0...sn] 可以加上y[n], 得到长度sn+1的一个以y[n]为结束字符的最长公共上升子序列, sn+1 > zn, 与假设矛盾.
O(n^2)对O(n^3)的一个优化.
memset(dp, 0, sizeof(dp));for (i = 1; i <= m; i++) { for(j = 1; j <= n; j++) { dp[i][j] = 0; if (x[i] != y[j]) { dp[i][j] = dp[i-1][j]; } else { for (k = 1; k < j; ++k) { if (dp[i][j] < dp[i - 1][k] && y[k] < y[j]) { dp[i][j] = dp[i - 1][k]; } } dp[i][j] += 1; }
for (k = 1; k < j; ++k) { if (dp[i][j] < dp[i - 1][k] && y[k] < y[j]) { dp[i][j] = dp[i - 1][k]; }}
for (k = 1; k < j; ++k) { if (dp[i][j] < dp[i - 1][k] && y[k] < x[i]) { dp[i][j] = dp[i - 1][k]; }}
for (i = 1; i <= m; i++) { mlen = 0; for(j = 1; j <= n; j++) { dp[i][j] = dp[i-1][j]; //更新mlen if (y[j] < x[i] && dp[i - 1][j] > mlen) { mlen = dp[i - 1][j]; } //计算dp[i][j] if (y[j] == x[i]) { dp[i][j] = mlen + 1; } }}
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int f[5005][5005];int a[5005],b[5005];int yh[5005];int pre[5005][5005];int main(){ int n; scanf("%d",&n); for (int i=1;i<=n;++i) scanf("%d",&a[i]); int m; scanf("%d",&m); for (int i=1;i<=m;++i) scanf("%d",&b[i]); int ans=0; int x=n; int y=m; for (int i=1;i<=n;++i){ int len=0; int last=0; for (int j=1;j<=m;++j){ f[i][j]=f[i-1][j]; if (a[i]>b[j]&&f[i-1][j]>len) len=f[i-1][j],last=j; if (a[i]==b[j]) f[i][j]=len+1,pre[i][j]=last; if (f[i][j]>ans){ y=j; ans=f[i][j]; } } } printf("%d\n",ans); int tail=0; while(ans--){ yh[++tail]=b[y]; while(a[x]!=b[y]) x--; y=pre[x][y]; x--; } for (int i=tail;i>=2;--i) printf("%d ",yh[i]); printf("%d\n",yh[1]); return 0;}
阅读全文
0 0
- 最长公共上升子序列
- 最长公共上升子序列
- 最长上升公共子序列
- 最长公共上升子序列
- 最长公共上升子序列
- 最长公共上升子序列
- 最长公共上升子序列
- 最长公共上升子序列
- 最长公共上升子序列
- 最长公共上升子序列
- 最长公共子上升序列
- 最长公共上升子序列
- 最长公共上升子序列
- 最长上升子序列、最长公共上升子序列
- 最长公共子序列,最长上升公共子序列
- 最长公共子序列、上升子序列、最长上升子序列、最长公共子串
- 最长上升子序列(LIS)&最长公共子序列(LCS)
- 最长上升子序列 最长公共子序列
- Substring with Concatenation of All Words--LeetCode
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- 数组
- POJ 1742/HDU2844 Coins 题解
- MachineLearning 学习之fisher判别
- 最长公共上升子序列
- Django 博客
- Unix-Linux编程实践教程——第六章
- 空间亚线性算法
- 在Linux(Ubuntu)中使用终端编译并运行.c和.cpp文件
- jqeruy时间处理
- Java设计模式知识-笔记六
- C++风格_作用域
- nginx服务器的搭建