Greatest Common Increasing Subsequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5444 Accepted Submission(s): 1755
Problem Description
This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence.
Input
Each
sequence is described with M - its length (1 <= M <= 500) and M
integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence itself.
Output
output print L - the length of the greatest common increasing subsequence of both sequences.
Sample Input
1
5
1 4 2 5 -12
4
-12 1 2 4
Sample Output
2
Source
Recommend
四种方法代码:
每一种都按照我觉得最容易理解的思路和最精简的写法写了,有些地方i 或者 i-1都可以,不必纠结。
#include<algorithm> #include<string> #include<string.h> #include<stdio.h> #include<iostream> using namespace std; #define N 505 int a[N],l1,l2,b[N],ma,f[N][N],d[N]; void solve1()//O(n^4) { ma = 0; memset(f, 0, sizeof(f) ); for(int i = 1; i <= l1; i++) for(int j = 1; j <= l2; j++) { if(a[i-1] == b[j-1]) { int ma1 = 0; for(int i1 = 1; i1 < i; i1++) for(int j1 = 1; j1 < j; j1++) if(a[i1-1] == b[j1-1] && a[i1-1] < a[i-1] && f[i1][j1] > ma1)//实际上a[i-1]==b[j1-1]可以省,因为既然f[i1][j1]+1>f[i][j]了, ma1 = f[i1][j1]; /*说明肯定a[i-1]==b[j1-1]了,因为这种解法只有当a[i-1]==b[j-1]时,f[i][j]才不等于0*/ f[i][j] = ma1 + 1; } ma = max(ma, f[i][j]); } cout<<ma<<endl; } void solve2()//O(n^3) { ma = 0; memset(f, 0, sizeof(f) ); for(int i = 1; i <= l1; i++) for(int j = 1; j <= l2; j++) { f[i][j] = f[i-1][j]; if(a[i-1] == b[j-1]) { int ma1 = 0; for(int j1 = 1; j1 < j; j1++) { if(b[j1-1] < b[j-1] && f[i-1][j1] > ma1) ma1 = f[i-1][j1]; } f[i][j] = ma1 + 1; } ma = max(ma, f[i][j]); } cout<<ma<<endl; } void solve3()//O(n^2) { memset(f, 0, sizeof(f) ); for(int i = 1; i <= l1; i++) { int ma1 = 0; for(int j = 1; j <= l2; j++) { f[i][j] = f[i-1][j];//带这种的一般都能压缩一维空间,也就是简化空间复杂度 if(a[i-1] > b[j-1] && f[i-1][j] > ma1) ma1 = f[i-1][j]; if(a[i-1] == b[j-1]) f[i][j] = ma1 + 1; } } ma = -1; for(int j = 1;j <= l2; j++) ma=max(ma,f[l1][j]); cout<<ma<<endl; } void solve4()//O(n^2)//优化空间复杂度 { ma = 0; memset(d, 0, sizeof(d) ); for(int i = 1; i <= l1; i++) { int ma1 = 0; for(int j = 1; j <= l2; j++) { if(a[i-1] > b[j-1] && d[j] > ma1) ma1 = d[j]; if(a[i-1] == b[j-1]) d[j] = ma1 + 1; } } ma = -1; for(int j = 1;j <= l2; j++) ma = max(ma, d[j]); cout<<ma<<endl; } int main() { int T;cin>>T; while(T--) { scanf("%d", &l1); for(int i = 0; i < l1; i++) scanf("%d", &a[i]); scanf("%d", &l2); for(int i = 0; i < l2; i++) scanf("%d", &b[i]); // solve1(); // solve2(); // solve3(); solve4(); if(T) printf(" "); } return 0; } /* 99 5 1 4 2 5 -12 4 -12 1 2 4 9 3 5 1 6 7 9 1 5 13 6 4 6 13 9 13 5 */