1. 程式人生 > >賊有意思[最長上升公共子序列](SAC大佬測試題)

賊有意思[最長上升公共子序列](SAC大佬測試題)

描述 cstring space 意思 clas 定義 tdi nbsp i++

題目描述
Awson 最近越來越蠢了,一天就只知道 zyys。
他定義了一個 zyys 數列:這個數列滿足:
1.是另外兩個數列 A,B 的公共子序列;
2.數列單調遞增。
現在他有一個問題,我們假設知道兩個長度均為 N 的序列 A,B,如何去找最長的 zyys
數列呢?由於他只會 zyys 了,他把這個問題交給了你。
輸入格式
第一行包含一個整數 N,表示序列 A,B 的長度;
接下來 2 行,每行 N 個數,表示序列 A,B。
輸出格式
一行,輸出最長的 zyys 數列。
輸入樣例
5
2 3 3 3 4
2 3 3 4 5
輸出樣例
3
數據範圍
對於 50%的數據,有 N <= 50
對於 100%的數據,有 N <= 5000

50分:

f[i][j]=f[i‘][j‘] (a[i]==b[j],a[i‘]<a[i],a[i‘]==b[j‘],i‘<i,j‘<j)

復雜度為O(n^4)

100分,只要稍作修改

我們令 f[i][j]表示A[1~i]以 B[j]為最後該序列的最後一個數的最長長度。

如果a[i]==b[j]則f[i][j]=maxlen(f[i-1][j‘])+1 (a[i]>b[j‘],j‘<j)

否則顯然f[i][j]=f[i-1][j]

maxlen那一部分邊循環邊更新就行了

 1 #include<iostream>
 2 #include<cstdio>
 3
#include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n; 7 int a[5001],b[5001]; 8 int f[5001][5001],ans; 9 int main() 10 { 11 int i,j,k,l; 12 cin>>n; 13 for (i=1; i<=n; i++) 14 { 15 scanf("%d",&a[i]); 16 } 17 for (i=1; i<=n; i++)
18 { 19 scanf("%d",&b[i]); 20 } 21 for (i=1; i<=n; i++) 22 { 23 int len=0; 24 for (j=1; j<=n; j++) 25 { 26 if (a[i]==b[j]) f[i][j]=len+1; 27 else f[i][j]=f[i-1][j]; 28 if (a[i]>b[j]&&f[i-1][j]>len) len=f[i-1][j]; 29 ans=max(ans,f[i][j]); 30 } 31 } 32 cout<<ans; 33 }

賊有意思[最長上升公共子序列](SAC大佬測試題)