1. 程式人生 > >最長公共上升子序列 (LIS+LCS+記錄)

最長公共上升子序列 (LIS+LCS+記錄)

tmp pri noi ace 經典問題 lcs pac bit 鏈接

【題目描述】

    給出兩個序列,求出最長公共上升子序列的長度,並輸出其中一個解。

【題目鏈接】

    http://noi.openjudge.cn/ch0206/2000/

【算法】

    經典問題,結合了LIS和LCS。

【代碼】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int len1,len2,i,j,ans,ri,rj;
 4 int s1[510],s2[510],rec[510][510],dp[510][510];
 5 void print(int x,int y)
 6 {
 7     switch(rec[x][y]) {
8 case -1: print(x-1,y); break; 9 case 0: printf("%d",s2[y]); break; 10 default: print(x-1,rec[x][y]),printf(" %d",s2[y]); 11 } 12 } 13 int main() 14 { 15 scanf("%d",&len1); 16 for(i=1;i<=len1;i++) scanf("%d",&s1[i]); 17 scanf("%d",&len2); 18 for
(i=1;i<=len2;i++) scanf("%d",&s2[i]); 19 for(i=1;i<=len1;i++) { 20 int val=0,tmp=0; 21 for(j=1;j<=len2;j++) { 22 if(s1[i]==s2[j]) dp[i][j]=val+1,rec[i][j]=tmp; 23 else dp[i][j]=dp[i-1][j],rec[i][j]=-1; 24 if(s1[i]>s2[j]&&dp[i-1
][j]>val) val=dp[i-1][j],tmp=j; 25 if(dp[i][j]>ans) ans=dp[i][j],ri=i,rj=j; 26 } 27 } 28 printf("%d\n",ans); 29 print(ri,rj); 30 return 0; 31 }

最長公共上升子序列 (LIS+LCS+記錄)