zoukankan      html  css  js  c++  java
  • DP基础(线性DP)总结

    DP基础(线性DP)总结

    前言:虽然确实有点基础......但凡事得脚踏实地地做,基础不牢,地动山摇,,,嗯!


    LIS(最长上升子序列)

    dp方程:dp[i]=max{dp[j]+1,a[j]<=a[i]}

    复杂度:O(n^2)


    LIS优化

    法一:数据结构无脑暴力优化

    ​ 以a[i]为数组下标,从1到a[i]访问最大值,再加一,进行更新

    法二:设h[k]表示dp值为k的最长上升子序列的最小值(有点贪心在里面)

    ​ 显然h[k]>=h[k-1](k>=2),证明:若存在h[k-1]>h[k],则h[k-1]可以从h[k]中转移,故不存在h[k]>=h[k-1]

    ​ 所以我们可以通过二分查找,找到一个最大的h[k]满足h[k]<=a[i],则dp[i]=k+1

    两种方法的复杂度都为O(nlogn)


    LCS(最长公共子序列)

    dp方程:

    dp[i][j]=max{dp[i-1][j-1]+1,a[i]==b[j]}
    dp[i][j]=max{dp[i-1][j],dp[i][j-1],a[i]!=b[j]}//若a[i]!=b[j]则说明a[i]或b[j]对于dp值无贡献
    

    复杂度:O(n^2)

    优化:嗯......少数有特殊性质的题目可以将LCS转化为优化LIS来做。


    LCIS(最长公共上升子序列)

    小声bb:最麻烦的来了

    先说复杂度O(n*m^2)的吧:

    设dp[i][j]表示a序列的前i个数和b序列的前j个数且以b[j]结尾构成的LCIS长度
    则若a[i]!=b[j]则需找到一个a[k]与b[j]匹配(1<=k<=i-1),故a[i]对于dp[i][j]的值无贡献,
    所以dp[i][j]=dp[i-1][j]
    若a[i]=b[j]则a[i]与b[j]匹配,所以dp[i][j]=max{dp[i-1][t],1<=t<=j-1且b[t]<=b[j]}
    

    然后是复杂度O(nmlogm)的:

    考虑类似于优化LIS的优化
    设h[k]表示dp值为k的LCIS的最后一位b[t]的最小值,显然h[k]也一定满足h[k]>=h[k-1]
    故可以通过二分查找来找到最大的h[k]满足h[k]<=b[j],则dp[i][j]=k+1
    

    最后是复杂度O(n*m)的:

    我们需要找到b[t]<b[j],我们发现,在dp过程中,外层循环是i,内层循环是j,也就是说对于同一组内层循环来讲,i的值是一定的,而j是从一到n,故我们在循环的过程中,对于同一组内层循环来讲,我们可以记录一个t值使得 dp[i-1][t]的值最大且b[t]<=b[j]
    for(int i=1;i<=n;i++)
    {
        int t=0;
        for(int j=1;j<=m;j++)
        {
             if(a[i]!=b[j])dp[i][j]=dp[i-1][j];
             if(a[i]==b[j])
             {
                 dp[i][j]=dp[i-1][t]+1;
             }
            if(a[i]>b[j]&&dp[i-1][j]>dp[i-1][t])t=j;
        }
    }
    
  • 相关阅读:
    监听器
    过滤器
    连接池与分页
    jdbc优化
    jdbc入门
    web开发mysql基础
    自定义标签
    jsp基础
    会话管理入门
    19. Remove Nth Node From End of List C++删除链表的倒数第N个节点
  • 原文地址:https://www.cnblogs.com/Akaina/p/11226914.html
Copyright © 2011-2022 走看看