zoukankan      html  css  js  c++  java
  • 【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
  • 相关阅读:
    Hibernate 工作原理及为什么要用
    一款很好用的JQuery dtree树状图插件(一)
    android PopupWindow
    android 截屏工具类
    ubuntu 中文输入法
    Google GCM推送
    windows 安装配置 ant
    (转)Angular中的拦截器Interceptor
    flex 布局 自己做的demo
    flex布局 (转)
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10659741.html
Copyright © 2011-2022 走看看