zoukankan      html  css  js  c++  java
  • 最长公共子序列 LCS

    也是DP入门题,紫书第九章

    这里讲得很清晰:

    http://www.cnblogs.com/xudong-bupt/archive/2013/03/15/2959039.html

    n^2模板:

    int n,m;
    
    char a[MAXN],b[MAXN],res[MAXN];
    
    int dp[MAXN][MAXN],dir[MAXN][MAXN];
    //dir 1斜上,2左,3上
    
    void lcs(int al,int bl)
    {
        int i,j;
        for(i=1;i<=al;i++)
        {
            for(j=1;j<=bl;j++)
            {
                if(a[i-1] == b[j-1])
                {
                    dp[i][j] = dp[i-1][j-1]+1;
                    dir[i][j] = 1;
                }
                else if(dp[i-1][j]>dp[i][j-1])
                {
                    dp[i][j] = dp[i-1][j];
                    dir[i][j] = 3;
                }
                else
                {
                    dp[i][j] = dp[i][j-1];
                    dir[i][j] = 2;
                }
            }
        }
    }
    
    void getlcs(int al,int bl)
    {
        int i = al;
        int j = bl;
        int k = 0;
        while(i && j)
        {
            if(dir[i][j] == 1)
            {
                res[k++] = a[i-1];
                i--;j--;
            }
            else if(dir[i][j]==2) j--;
            else if(dir[i][j]==3) i--;
        }
        for(int v = k-1;v>=0;v--) pf("%c",res[v]);
    }

    nlogn复杂度:

    这个不是稳定的nlogn,事实上,LCS没有稳定的nlogn算法,只有在一定限制条件下才有可能达到。

    这里的限制条件是:

    A中元素在B中的序号对数很少

    若是aaaa,aaaaaaa的话,则是n*nlogn复杂度,比普通lcs还慢

    具体讲解:http://blog.csdn.net/wdq347/article/details/9001005

    (1) 对序列B排序

    (2) 计算A中每个元素在B中的序号,并构成新序列

    (3) 使用LIS的方法计算最长严格递增子序列

    (4) 获取最长公共子序列

    性能分析:

    (1) 排序复杂度为nlogn

    (2) 获取一个元素在B中的序号的复杂度,最小为logn,最大为n,获取所有元素的复杂度为 nlogn === n*n

    (3) LIS 复杂度为nlogn

    因此总体复杂度在nlogn 到 n*n logn之间,但如果(2) 步骤中A中元素在B中的序号对数很少时,性能相当优越,在实际测试时,string 中均为小写字母,长度为10000的情况下,这种方法比普通的LCS快一倍以上;如果string 中的字符扩展成char,即0-255,则这种方法比普通的LCS快至少一个数量级

    模板:

    char a[MAXN],b[MAXN];
    int g[MAXN],s[MAXN];
    
    vector<int> p[26];
    
    int lcs(int al,int bl)
    {
        int i,j,z,y=0;
        for(i=0;i<=26;i++) p[i].clear();
        for(i=bl-1;i>=0;--i) p[b[i]-'a'].pb(i);
        for(i=0;i<al;++i)
            for(j=0,z=p[a[i]-'a'].size();j<z;++j)
                s[y++]=p[a[i]-'a'][j];
        mem(g,INF);
        int ans=0;
        for(i=0;i<y;++i)
        {
            int k=lower_bound(g,g+y,s[i])-g;
            ans = max(ans,k+1);
            g[k]=s[i];
        }
        return ans;
    }

    连续和不连续:

    http://www.cnblogs.com/xubenben/p/3330712.html

  • 相关阅读:
    http数据返回值
    刷新 返回
    微信平台上遇到的bug
    iscroll修改
    iscroll
    a标签的herf和click事件
    ios9+xcode7 适配笔记
    xsd、wsdl生成C#类的命令行工具使用方法
    xcode更新,想想也是醉了
    关于#define预处理指令的一个问题
  • 原文地址:https://www.cnblogs.com/qlky/p/5662179.html
Copyright © 2011-2022 走看看