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

    2017-09-02 15:06:57

    writer:pprp

    状态表示:

    f(n,m)表示s1[0..n]和s2[0..m]
    从0开始计数,最终结果是f(N-1,M-1)
    考虑四种情况:
      1/ s1[n] == s2[m] : f(n,m) = f(n-1,m-1)+1;
      2/ s1[n]是LCS的一部分,
      3/ s2[m]是LCS的一部分,
      4/ s1[n]和s2[m]都不是LCS的一部分
    状态转移:
      if(s1[n] == s1[m])
      f(n,m) = max(f(n-1,m-1)+1,f(n-1,m),f(n,m-1),f(n-1,m-1));
      f(n-1,m-1) 只可能小于 f(n-1,m-1)+1
      f(n,m-1)顶多跟f(n-1,m-1)+1的值相同,f(n-1,m)也是同理
      所以直接就是f(n-1,m-1)+1;
      if(s1[n] != s2[m])
      f(n,m) = max(f(n-1,m),f(n,m-1),f(n-1,m-1))
      已知f(n-1,m-1)小于等于f(n-1,m)
      最后状态为f(n,m) = max(f(n-1,m),f(n,m-1));
    结果在上边已经分析过了

    代码如下:两种都是对的,不同的表达方式而已;

    /*
    @theme:最长公共子序列
    @writer:pprp
    @begin:15:37
    @end:16:29
    @declare:LCS
    @error:从1开始读入的话,用strlen也要从1开始测才可以
    @date:2017/9/2
    */
    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    char s1[1010],s2[1010];
    int dp[1010][1010];
    
    /*
    状态表示:f(n,m)表示s1[0..n]和s2[0..m]
    从0开始计数,最终结果是f(N-1,M-1)
    考虑四种情况:
    1/ s1[n] == s2[m] : f(n,m) = f(n-1,m-1)+1;
    2/ s1[n]是LCS的一部分,
    3/ s2[m]是LCS的一部分,
    4/ s1[n]和s2[m]都不是LCS的一部分
    状态转移:
    if(s1[n] == s1[m])
        f(n,m) = max(f(n-1,m-1)+1,f(n-1,m),f(n,m-1),f(n-1,m-1));
        f(n-1,m-1) 只可能小于 f(n-1,m-1)+1
        f(n,m-1)顶多跟f(n-1,m-1)+1的值相同,f(n-1,m)也是同理
        所以直接就是f(n-1,m-1)+1;
    if(s1[n] != s2[m])
        f(n,m) = max(f(n-1,m),f(n,m-1),f(n-1,m-1))
        已知f(n-1,m-1)小于等于f(n-1,m)
        最后状态为f(n,m) = max(f(n-1,m),f(n,m-1));
    结果在上边已经分析过了
    */
    
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        //从0开始
        while(~scanf("%s%s",s1+1,s2+1))
        {
            memset(dp,0,sizeof(dp));
    
            int n = strlen(s1+1);
            int m = strlen(s2+1);
    
            for(int i = 1; i <= n ; i++)
            {
                for(int j = 1 ; j <= m ; j++)
                {
                    if(s1[i] == s2[j])
                        dp[i][j] = dp[i-1][j-1]+1;
                    else
                        dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
                }
            }
            cout << dp[n][m] << endl;
        }
        return 0;
    }
    
    
    /*
    int main()
    {
        freopen("in.txt","r",stdin);
        while(~scanf("%s%s",s1+1,s2+1))
        {
            memset(dp,0,sizeof(dp));
            int i,j;
            for(i = 1; s1[i] ; i++)
            {
                for(j = 1; s2[j]; j++)
                {
                    if(s1[i] == s2[j])
                        dp[i][j] = dp[i-1][j-1]+1;
                    else
                        dp[i][j] = max(dp[i][j-1],dp[i-1][j]);
                }
            }
            cout << dp[i-1][j-1] << endl;
        }
    }
    */

     

     

  • 相关阅读:
    定义函数
    变量与常量
    字符串与格式化
    字符串与编码
    字符编码
    元组-tuple
    列表-list
    分支和循环
    润乾配置连接kingbase(金仓)数据库
    润乾报表在proxool应用下的数据源配置
  • 原文地址:https://www.cnblogs.com/pprp/p/7466793.html
Copyright © 2011-2022 走看看