• [JOYOI] 1071 LCIS


    拖了好久的LCIS

    f[i][j]表示a串前i个,b串以b[j]结尾的LCIS长度。

    转移时考虑a[i]和b[j]是否相等,如果不等:

    那么既然是以j结尾,说明a串前i-1位有一个字符和b匹配了,所以由f[i-1][j]转移来(i-1涵盖所有方案)

    如果相等,那么考虑由什么转移来

    f[i-1][k]是一个前驱状态,既然a[i]匹配了,就只能考虑前i-1位了,由于定义如此,所以可以“笼统地”从f[i-1][]转移来,第二维就得枚举j前面的k,且b[k]<b[j],满足递增性质

    这样做是O(n^3)的复杂度,考虑优化一下。

    对于一个相等的状态,这里O(n)的转移就是优化的瓶颈了,看看怎么做。

    f[i][j]只能从f[i-1][k]转移来,k还得小于j,所以可以一边循环j一边用mx记录f[i][1~j-1]的最大值,前提是b[j]>a[i]。

    这样转移就可以写成f[i][j]=mx+1了,O(n^2)的复杂度。

    第一维可以像01背包一样压下来,空间O(n)

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    const int MAXN=3005;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    int n;
    int a[MAXN],b[MAXN];
    
    int f[MAXN][MAXN];
    
    int main(){
        n=rd();
        for(int i=1;i<=n;i++) a[i]=rd();
        for(int i=1;i<=n;i++) b[i]=rd();
        for(int i=1;i<=n;i++){
            int mx=0;
            for(int j=1;j<=n;j++){
                if(a[i]>b[j]) mx=max(mx,f[i-1][j]);
                if(a[i]!=b[j]){
                    f[i][j]=f[i-1][j];
                    continue;
                }
                if(a[i]==b[j]) f[i][j]=mx+1;
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++) ans=max(ans,f[n][i]);
        cout<<ans;
        
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9282854.html

  • 相关阅读:
    数据库分表分库
    rabbitMq 集群
    马哥博客作业第七周
    马哥博客作业第六周
    马哥博客作业第一阶段考试
    马哥博客作业第四周
    马哥博客作业第三周
    马哥博客作业第二周
    马哥博客作业第一周
    03-MySQL数据库表的基本操作
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9282854.html
Copyright © 2020-2023  润新知