Codeforces Beta Round #10 D. LCIS(DP&LCIS)
2015-10-26 11:45
183 查看
D. LCIS
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
This problem differs from one which was on the online contest.
The sequence a1, a2, ..., an is
called increasing, if ai < ai + 1 for i < n.
The sequence s1, s2, ..., sk is
called the subsequence of the sequence a1, a2, ..., an,
if there exist such a set of indexes 1 ≤ i1 < i2 < ... < ik ≤ n that aij = sj.
In other words, the sequence s can be derived from the sequence aby
crossing out some elements.
You are given two sequences of integer numbers. You are to find their longest common increasing subsequence, i.e. an increasing sequence of maximum length that is the subsequence of both sequences.
Input
The first line contains an integer n (1 ≤ n ≤ 500)
— the length of the first sequence. The second line contains nspace-separated integers from the range [0, 109] —
elements of the first sequence. The third line contains an integer m (1 ≤ m ≤ 500)
— the length of the second sequence. The fourth line contains m space-separated integers from the range [0, 109] —
elements of the second sequence.
Output
In the first line output k — the length of the longest common increasing subsequence. In the second line output the subsequence itself. Separate
the elements with a space. If there are several solutions, output any.
Sample test(s)
input
output
input
output
题意:
给你长度分别为n,m(1<=n,m<=500)的序列。要你求这两个序列的最长公共上升子序列。
思路:
最长公共子序列做过。最长上升子序列也做过。可是这题时最长公共上升子序列。。。解法肯定还是dp拉。
感觉这题的dp方程的思想非常不错,体现了一种加强约束的思想。dp[i][j]表示。处理完A序列的前i个,且上升序列以B序列的B[j]结尾的最长子序列。感觉这个把状态体现以什么结尾是非常不错的思想。然后转移显而易见了。
if(A[i]==B[j])
dp[i][j]=dp[i-1][k];//k是小于j且B[k]<B[j]
else
dp[i][j]=dp[i-1][j];
我们能够i,j循环这样就能够省掉找k的时间。复杂度O(n*m)
具体见代码:
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
This problem differs from one which was on the online contest.
The sequence a1, a2, ..., an is
called increasing, if ai < ai + 1 for i < n.
The sequence s1, s2, ..., sk is
called the subsequence of the sequence a1, a2, ..., an,
if there exist such a set of indexes 1 ≤ i1 < i2 < ... < ik ≤ n that aij = sj.
In other words, the sequence s can be derived from the sequence aby
crossing out some elements.
You are given two sequences of integer numbers. You are to find their longest common increasing subsequence, i.e. an increasing sequence of maximum length that is the subsequence of both sequences.
Input
The first line contains an integer n (1 ≤ n ≤ 500)
— the length of the first sequence. The second line contains nspace-separated integers from the range [0, 109] —
elements of the first sequence. The third line contains an integer m (1 ≤ m ≤ 500)
— the length of the second sequence. The fourth line contains m space-separated integers from the range [0, 109] —
elements of the second sequence.
Output
In the first line output k — the length of the longest common increasing subsequence. In the second line output the subsequence itself. Separate
the elements with a space. If there are several solutions, output any.
Sample test(s)
input
7 2 3 1 6 5 4 6 4 1 3 5 6
output
3 3 5 6
input
5 1 2 0 2 1 3 1 0 1
output
2 0 1
题意:
给你长度分别为n,m(1<=n,m<=500)的序列。要你求这两个序列的最长公共上升子序列。
思路:
最长公共子序列做过。最长上升子序列也做过。可是这题时最长公共上升子序列。。。解法肯定还是dp拉。
感觉这题的dp方程的思想非常不错,体现了一种加强约束的思想。dp[i][j]表示。处理完A序列的前i个,且上升序列以B序列的B[j]结尾的最长子序列。感觉这个把状态体现以什么结尾是非常不错的思想。然后转移显而易见了。
if(A[i]==B[j])
dp[i][j]=dp[i-1][k];//k是小于j且B[k]<B[j]
else
dp[i][j]=dp[i-1][j];
我们能够i,j循环这样就能够省掉找k的时间。复杂度O(n*m)
具体见代码:
#include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f; const int maxn=100010; typedef long long ll; int dp[550][550],A[550],B[550],path[550][550],n,m; bool print(int x) { if(!x) return false; if(print(path [x])) printf(" %d",B[x]); else printf("%d",B[x]); return true; } int main() { int i,j,tp,ans,pos; while(~scanf("%d",&n)) { for(i=1;i<=n;i++) scanf("%d",&A[i]); scanf("%d",&m); for(i=1;i<=m;i++) scanf("%d",&B[i]); memset(dp,0,sizeof dp); for(i=1;i<=n;i++) { tp=pos=0; for(j=1;j<=m;j++) { dp[i][j]=dp[i-1][j]; path[i][j]=path[i-1][j]; if(A[i]==B[j]&&tp+1>dp[i][j]) dp[i][j]=tp+1,path[i][j]=pos; if(B[j]<A[i]&&dp[i-1][j]>tp) tp=dp[i-1][j],pos=j; } } ans=1; for(i=1;i<=m;i++) if(dp [i]>dp [ans]) ans=i; printf("%d\n",dp [ans]); if(dp [ans]) print(ans); printf("\n"); } return 0; }
相关文章推荐
- 一棵开花的树
- 查到的小波讲解
- Alert 弹提示信息的5种方法
- Java——IO流(二)
- Jsp 入门 - 一个简单的web项目
- Mesos&PaaS系列文章之五——负载均衡与服务发现
- 九度OJ 1200:最大的两个数 (最值)
- PHP 数据类型
- 在windows直接运行Qt编译出来的可执行程序出现了如下提示错误: this application has requested the runtime to terminate it an unu
- 自定义属性
- iOS 关于本地持久化存储的探讨
- bash实例-参数/函数/统计IP
- 九度OJ 1200:最大的两个数 (最值)
- 【Android开发进阶】Android屏幕适配全攻略(最权威的官方适配指导)
- android 轻量级曲线图的绘制
- 日报2015/10/26(极客学院安卓视频学习)
- maven在myeclipse下运行mvn出现 No goals have been specified for this build.
- 我的学习笔记(一)
- (Chrome42)Lodop总计页面提示“未安装”要么“请升级”可能的原因和解决方案
- C#四舍五入保留一位小数