CH5101 LCIS

CH5101 LCIS

题意:

求两个长度不超过3000的序列的最长公共上升子序列

思路: 

 

  • 朴素解法:用f[i,j]表示a1~ai与b1~bj可以构成的以bj为结尾的LCIS的长度,三重循环求解:
for(res i=1 ; i<=n ; i++)
    for(res j=1 ; j<=m ; j++)
        if(a[i]==b[j])
        {
           for(res k=1 ; k<j ; k++)
                if(b[k]<a[i])//a[i]=b[j] 
                   f[i][j]=max(f[i][j],f[i-1][k]+1);
        }
        else
            f[i][j]=f[i-1][j]; 

 

  • 经过观察可以发现:当外层的i固定时,条件b[k]<a[i]也是固定的,所以当j增加1时,k的取值范围也只增加了1,即只有j可能进入新的决策集合,则可以优化为两重循环:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int N=3010;
 7 int a[N],b[N];
 8 int f[N][N];
 9 int n;
10 
11 int main()
12 {
13     scanf("%d",&n);
14     for(int i=1 ; i<=n ; i++) scanf("%d",&a[i]);
15     for(int i=1 ; i<=n ; i++) scanf("%d",&b[i]);
16     
17     for(int i=1 ; i<=n ; i++)
18     {
19         int val=0;//表示决策集合(即f[i-1][k]的最大值) 
20         for(int j=1 ; j<=n ; j++)
21         {
22             if(a[i]==b[j]) f[i][j]=val+1;
23             else f[i][j]=f[i-1][j];
24             if(b[j]<a[i])//更新决策集合 
25                 val=max(val,f[i-1][j]);
26         }
27     }
28     int ans=1;
29     for(int i=1 ; i<=n ; i++)
30         ans=max(ans,f[n][i]);
31     printf("%d\n",ans);
32     return 0;    
33 } 
View Code

 

 

 

 

 

 

  

posted @ 2019-02-12 09:42  孑行  阅读(201)  评论(0编辑  收藏  举报