最長公共上升子序列 (LIS+LCS+記錄)
阿新 • • 發佈:2018-08-01
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+記錄)