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
output
input
output
两个数列用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;
}
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;
}
相关文章推荐
- LCIS最长上升公共子序列(HDU 1423)
- dpPOJ 2027 LCIS(最长上升公共子序列)
- 最长公共上升子序列 LCIS
- hdu 1423 Greatest Common Increasing Subsequence(最长公共上升子序列、LCIS)
- Vijos-2164 神秘的咒语 [LCIS最长公共上升子序列]
- 最长公共上升子序列 LCIS
- ACM模板——最长公共上升子序列 LCIS
- 最长上升公共子序列(LCIS)
- HDU 5904 LCIS (最长公共上升序列)
- Codevs 2185 最长公共上升子序列 LCIS
- HDU 1423 最长上升公共子序列(LCIS)
- HDU 5904 LCIS (最长公共上升序列)
- (LCIS)最长公共上升子序列 ZOJ 2432
- hdu 1423 最长上升公共子序列 LCIS 模板题
- 最长公共上升子序列||LCIS
- HDU 5904 LCIS(最长上升公共子序列)
- Codevs_P2185 最长公共上升子序列(LCIS)
- LCIS 最长公共上升子序列
- hdoj1423 最长上升公共子序列
- “最长上升子序列,最大连续子序列和,最长公共子串”的Java实现