【CH5101】LCIS

最长公共上升子序列的模板题,仿照LCS和LIS的状态定义方式,我们定义f[i][j]表示a1~ai与b1~bj构成的以bj结尾的LCIS的长度,显然答案为max{f[n][i]}.

当ai≠bj时,f[i][j]=f[i-1][j].

当ai=bj时,f[i][j]=max{f[i-1][k]+1}   (b[k]<b[j])

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 inline int read() {
 5     int ret=0,f=1;
 6     char c=getchar();
 7     while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
 8     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
 9     return ret*f;
10 }
11 using namespace std;
12 int n,a[3010],b[3010],f[3010][3010];
13 int main() {
14     n=read();
15     for(int i=1;i<=n;i++) a[i]=read();
16     for(int i=1;i<=n;i++) b[i]=read();
17     a[0]=b[0]=-999999999;
18     for(int i=1;i<=n;i++) {
19         for(int j=1;j<=n;j++) {
20             if(a[i]==b[j]) {
21                 for(int k=0;k<j;k++)
22                     if(b[k]<a[i]) f[i][j]=max(f[i][j],f[i-1][k]+1);
23             }
24             else f[i][j]=f[i-1][j];
25         }
26     }
27     int ans=0;
28     for(int i=0;i<=n;i++)    
29         ans=max(ans,f[n][i]);
30     printf("%d",ans);
31     return 0;
32 }
TLE Code

时间复杂度为O(n3)。当n=3000时无法通过。

仔细思考:第二层循环当j变为j+1时,i是一个定值,也就是说bk<ai的条件是固定的。当j增加1时,k的取值范围从0≤k<j变为0≤k<j+1.而0≤k<j的部分我们已经计算过一遍,因此,我们用一个变量记录0≤k<j当中f[i-1][k]的最大值,在与新的f[i-1][k]比较,这样就能在O(1)的时间里完成转移。因此时间复杂度降为O(n2)。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 inline int read() {
 5     int ret=0,f=1;
 6     char c=getchar();
 7     while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
 8     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
 9     return ret*f;
10 }
11 using namespace std;
12 int n,a[3010],b[3010],f[3010][3010];
13 int main() {
14     scanf("%d",&n);
15     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
16     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
17     a[0]=b[0]=-999999999;
18     for(int i=1;i<=n;i++) {
19         int val=0;
20         if(b[0]<a[i]) val=f[i-1][0];
21         for(int j=1;j<=n;j++) {
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]) val=max(val,f[i-1][j]);
25         }
26     }
27     int ans=0;
28     for(int i=0;i<=n;i++)    
29         ans=max(ans,f[n][i]);
30     printf("%d",ans);
31     return 0;
32 }
AC Code

猜你喜欢

转载自www.cnblogs.com/shl-blog/p/10659741.html