week10-B-LIS&LCS

题意描述:

东东有两个序列A和B。他想要知道序列A的LIS和序列AB的LCS的长度。

注意,LIS为严格递增的,即a1<a2<…<ak(ai<=1,000,000,000)。

Input

第一行两个数n,m(1<=n<=5,000,1<=m<=5,000)
第二行n个数,表示序列A
第三行m个数,表示序列B

Output

输出一行数据ans1和ans2,分别代表序列A的LIS和序列AB的LCS的长度

思路:

LIS:定义状态fi表示以ai结尾的最长上升序列的结果;则有f1 = 1;状态转移:fi = max{fj|j < i ^ Aj < Ai} + 1。最后挑出最大者即可。
LCS:定义状态f[i][j]表示A1,A2…Ai和B1,B2…Bj的LCS长度;则有初始时f[1][0]=f[0][1]=f[0][0]=0;当Ai == Bj时,f[i][j] = f[i-1][j-1] + 1,否则f[i][j] = max(f[i-1][j],f[i][j-1])。最后答案为f[n][n]。

代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 int m,n;
 6 const int maxn = 5010;
 7 long a[maxn],b[maxn];
 8 
 9 int lis[maxn],lcs[maxn][maxn];
10 int res_lis,res_lcs,temp;
11 
12 int main()
13 {
14     ios::sync_with_stdio(false);
15     cin>>n>>m;
16     for(int i=1;i<=n;++i)
17         cin >> a[i];
18     for(int j=1;j<=m;++j)
19         cin >> b[j];
20         
21     lis[1] = 1;
22     res_lis = res_lcs = 0;
23     for(int i=1;i<=n;++i)
24     {
25         temp = 0;
26         for(int j=1;j<i;++j)
27             if(a[j] < a[i])temp=max(temp,lis[j]);
28         lis[i]=temp+1;
29         res_lis=max(res_lis,lis[i]);
30     }
31     
32     lcs[1][0]=lcs[0][1]=lcs[0][0]=0;
33     for(int i=1;i<=n;++i)
34     for(int j=1;j<=m;++j)
35     {
36         if(a[i] == b[j])
37             lcs[i][j] = lcs[i-1][j-1] + 1;
38         else lcs[i][j] = max(lcs[i-1][j],lcs[i][j-1]);
39     }        
40     cout<<res_lis<<" "<<lcs[n][m];
41     return 0;
42 }
原文地址:https://www.cnblogs.com/liuzhuan-xingyun/p/13053481.html