您的位置:首页 > 其它

Codeforces Beta Round #10-D. LCIS(最长上升公共子序列)

2016-09-14 18:39 351 查看
原题链接

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 indexes1 ≤ i1 < i2 < ... < ik ≤ n that aij = sj.
In other words, the sequence s can be derived from the sequence a by
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 n space-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.

Examples

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


两个数列用a, b数组表示,用dp[i][j]表示a数组的前i个元素和b数组的前j个元素,以b[j]结尾的最长公共上升子序列的长度,

当a[i] != b[j] 时 dp[i][j] = dp[i-1][j];

当a[i] == b[j] 时, dp[i][j] = max(dp[i-1][k]) + 1(k < j 且b[j] > b[k])

#include <bits/stdc++.h>
#define maxn 505
#define MOD 1000000007
using namespace std;
typedef long long ll;

int dp[maxn][maxn], a[maxn], b[maxn], pre[maxn], t = 0;
void print(int h){
if(pre[h]){
print(pre[h]);
}
if(t == 0){
printf("%d", b[h]);
t = 1;
}
else
printf(" %d", b[h]);
}
int main(){

// freopen("in.txt", "r", stdin);
int n, m;

scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", a+i);
scanf("%d", &m);
for(int j = 1; j <= m; j++)
scanf("%d", b+j);
for(int i = 1; i <= n; i++){
int maxs = 0, h = 0;
for(int j = 1; j <= m; j++){
dp[i][j] = dp[i-1][j];
if(a[i] > b[j] && dp[i-1][j] > maxs){
maxs = dp[i-1][j];
h = j;
}
if(a[i] == b[j]){
dp[i][j] = maxs + 1;
pre[j] = h;
}
}
}
int maxs = 0, h;
for(int i = 1; i <= m; i++){
if(dp
[i] > maxs){
maxs = dp
[i];
h = i;
}
}
printf("%d\n", maxs);
if(maxs){
print(h);
puts("");
}
return 0;
}

dp数组可以想01背包中的滚动数组一样优化为1wei维
#include <bits/stdc++.h>
#define maxn 505
#define MOD 1000000007
using namespace std;
typedef long long ll;

int dp[maxn], a[maxn], b[maxn], pre[maxn], t = 0;
void print(int h){
if(pre[h]){
print(pre[h]);
}
if(t == 0){
printf("%d", b[h]);
t = 1;
}
else
printf(" %d", b[h]);
}
int main(){

// freopen("in.txt", "r", stdin);
int n, m;

scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", a+i);
scanf("%d", &m);
for(int j = 1; j <= m; j++)
scanf("%d", b+j);
for(int i = 1; i <= n; i++){
int maxs = 0, h = 0;
for(int j = 1; j <= m; j++){
if(a[i] > b[j] && maxs < dp[j]){
maxs = dp[j];
h = j;
}
if(a[i] == b[j]){
dp[j] = maxs + 1;
pre[j] = h;
}
}
}
int maxs = 0, h;
for(int i = 1; i <= m; i++){
if(dp[i] > maxs){
maxs = dp[i];
h = i;
}
}
printf("%d\n", maxs);
if(maxs){
print(h);
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: