zoukankan      html  css  js  c++  java
  • CF10D LCIS&&Acwing 272

    一道经典(DP)

    LCS

    [f[i][j]=f[i-1][j-1]+1;(i,j>0,a[i]=b[j]) ]

    [f[i][j]=max(f[i][j-1],f[i-1][j]);(i,j>0,a[i] ot=b[j]) ]

    其中,f[i][j]a序列前i个元素与b序列前j个元素的(LCS)长度

    LIS

    [f[i]=max~f[j]+1~(j<i,a[j]<a[i]) ]

    f[i]为以第i个元素结尾的(LIS)长度。

    LCIS

    我们想办法糅合这两种动态规划的思想,设f[i][j]代表的是a序列前i个元素与b序列前j个元素的(LCIS)长度(最长公共上升子序列),t为最长(LCIS)的结尾元素位置,我们可以推出状态转移方程

    [f[i][j]=f[i-1][j]~(a[i] ot=b[j]) ]

    [f[i][j]=max(f[i-1][j],f[i-1][t]+1)~(a[i]=b[j]) ]

    最后,再转移时储存位置,输出

    Code One

    二维

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<string>
    #define ll long long
    #define maxn 550
    #define inf 2147483647
    #define mod 10003
    #define eps 1e-6
    #define pi acos(-1.0)
    #define de(x) ((x)*(x))
    using namespace std; 
    inline int read(){
        int x=0,f=1; char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    int n,a[maxn],b[maxn],f[maxn][maxn],g[maxn][maxn];
    inline void put(int x){
    	if(!x) return;
    	put(g[n][x]);
    	printf("%d ",b[x]); 
    }
    signed main(){
    	n=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	int m=read(),p=0;
    	for(int i=1;i<=m;i++) b[i]=read();
    	for(int i=1,t=0;i<=n;++i,t=0)
        for(int j=1;j<=m;++j){
            f[i][j]=f[i-1][j];      
            g[i][j]=g[i-1][j];
            if(a[i]==b[j]&&f[i-1][t]+1>f[i][j]){
                f[i][j]=f[i-1][t]+1;
                g[i][j]=t;  
            }
            if(b[j]<a[i]&&f[i-1][j]>f[i-1][t]) t=j;
            //检查t是否为最长LCIS的结尾元素位置
        }
    	for(int i=1;i<=m;i++) 
    	if(f[n][i]>f[n][p]) p=i;
    	printf("%d
    ",f[n][p]);
    	put(p);
        return 0;
    }
    

    优化

    分析状态转移方程可知f[i][j]都是由f[i-1][j]得来的,因此可以优化空间,设f[i]代表的是a序列前i个元素与b序列的LCIS长度,t为最长LCIS的结尾元素位置,新的状态转移方程为

    [f[i]=f[t]+1~(a[i]=b[j]) ]

    Code Two

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<string>
    #define ll long long
    #define maxn 550
    #define inf 2147483647
    #define mod 10003
    #define eps 1e-6
    #define pi acos(-1.0)
    #define de(x) ((x)*(x))
    using namespace std; 
    inline int read(){
        int x=0,f=1; char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    int n,a[maxn],b[maxn],f[maxn],g[maxn];
    inline void put(int x){
    	if(!x) return;
    	put(g[x]);
    	printf("%d ",b[x]); 
    }
    signed main(){
    	n=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	int m=read(),p=0;
    	for(int i=1;i<=m;i++) b[i]=read();
    	for(int i=1,t=0;i<=n;++i,t=0)
        for(int j=1;j<=m;++j){
            if(a[i]==b[j]){
                f[j]=f[t]+1;
                g[j]=t;  
            }
            if(b[j]<a[i]&&f[j]>f[t]) t=j;
        }
    	for(int i=1;i<=m;i++) 
    	if(f[i]>f[p]) p=i;
    	printf("%d
    ",f[p]);
    	put(p);
        return 0;
    }
    

    0.02.jpg

    效果显著

    (P.S)可以写写Acwing 272

  • 相关阅读:
    Elasticsearch节点下线(退役)and unassigned shards
    详解Hbase架构原理
    docker安装(yum方式)
    矩形的逆时针蛇形填数
    CentOS7安装iptables防火墙
    Linux:-bash: ***: command not found
    两个大数相乘JAVA版
    SQL Server 2012时出现命名管道提供程序: 无法打开与 SQL Server 的连接
    jstl函数库及自定义函数库
    This Android SDK requires Android Developer Toolkit version 23.0.0 or above
  • 原文地址:https://www.cnblogs.com/cbyyc/p/11455793.html
Copyright © 2011-2022 走看看