zoukankan      html  css  js  c++  java
  • hdu 1159 dp(最长公共子序列)

    在这附一个别人的网址,是求LCS时的空间优化

    http://blog.sina.com.cn/s/blog_7826c4dd01011em0.html

    我贴两个代码,空间复杂度分别为 O(2*n)的和O(n)的

    空间复杂度O(2*n)
    //hdu 1159  dp(最长公共子序列)
    //以下是空间复杂度为O(2*n)的代码
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    
    using namespace std;
    
    #define N 3000
    
    char tmp1[N], tmp2[N];
    //这里本来应该是 dp[N][N]的,应为求LCS时,用第一串的
    //第i 个字符与第二串匹配时,时从前一个字符跟第二串每个字符匹配
    //得到的最优值转移过来的,具体看下面代码和注释
    int dp[2][N];
    
    int LCSL(char *t1, char *t2)
    {
        memset(dp, 0, sizeof(dp));
        int len1= strlen(t1), len2 = strlen(t2);
        //求LCSL时就是
        for(int i = 0; i < len1; ++i)
        {   //第一串 的 i字符和第二串的 j字符匹配时
            for(int j = 0; j < len2; ++j)
            {  //若匹配成功,则dp[i][j] = dp[i-1][j-1]+1,意思是从
               //t1的 前 i-1个字符和t2串的 前 j-1个字符匹配中最优值+1
                if(t1[i] == t2[j])  //这里本可以(i-1)&1 可是i从0开始所以(i+1)&1也一样
                    dp[i&1][j] = dp[ (i+1)&1 ][j-1] + 1;
                else    //若匹配不成功,则取 t1第i个 和t2第j-1个匹配时的最优值或i-1 和 j匹配
                    dp[i&1][j] = max(dp[i&1][j-1], dp[ (i+1)&1 ][j]);//时的最优值 中的最大值
            }
        //在求c(i,j)时,只用到了c(i-1,j)和c(i,j-1),所以可以用滚动数组来优化
    
        }
        return dp[(len1-1)&1][len2-1];
    }
    
    int main()
    {
        while(scanf("%s%s", tmp1, tmp2) != EOF)
        {
            printf("%d\n", LCSL(tmp1, tmp2));
        }
        return 0;
    }
    空间复杂度O(n)
    //hdu 1159  dp(最长公共子序列)
    //以下是空间复杂度为O(n)的代码
    #include <stdio.h>
    #include <string.h>
    
    #define N 3005
    
    int n;
    char tmp1[N], tmp2[N];
    //这里本来应该是 dp[N][N]的,应为求LCSL时,用第一串的
    //第i 个字符与第二串匹配时,时从前一个字符跟第二串每个字符匹配
    //得到的最优值转移过来的,具体看下面代码和注释
    int dp[N];
    
    int max(int a, int b)
    {
        return a > b ? a : b;
    }
    
    int LCSL(char *t1, char *t2)
    {
        int m, len1 = strlen(t1), len2 = strlen(t2);
        memset(dp, 0, sizeof(dp));
    
        //求LCS时就是
        for(int i = len1-1; i >= 0; --i)
        {   //第一串 的 i字符和第二串的 j字符匹配时
            int tmp = 0;    //tmp记录对角线的值,即从前往后推的dp[i-1][j-1]
            for(int j = len2-1; j >= 0; --j)
            {
                m = max(dp[j], dp[j+1]);
                if(t1[i] == t2[j])
                {
                    m = max(tmp+1, m);
                }
                tmp = dp[j];    //继续取对角线的值
                dp[j] = m;    //覆盖当前值
            }
        }
        return dp[0];
    }
    
    int main()
    {
        while(scanf("%s%s", tmp1, tmp2) != EOF)
        {
            printf("%d\n", LCSL(tmp1, tmp2));
        }
        return 0;
    }
  • 相关阅读:
    3.8快乐
    只剩一个人了
    需求分析
    再也不看皇马比赛
    最近蛮忙,没头绪
    ↗☻【响应式Web设计 HTML5和CSS3实战 #BOOK#】第5章 CSS3:选择器、字体和颜色模式
    ↗☻【高性能网站建设进阶指南 #BOOK#】第12章 尽早刷新文档的输出
    ↗☻【响应式Web设计 HTML5和CSS3实战 #BOOK#】第4章 响应设计中的HTML5
    ↗☻【JavaScript】code
    ↗☻【高性能网站建设进阶指南 #BOOK#】第11章 划分主域
  • 原文地址:https://www.cnblogs.com/gabo/p/2446795.html
Copyright © 2011-2022 走看看