zoukankan      html  css  js  c++  java
  • 51nod1006最长公共子序列(lcs输出路径)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006

    分析和思路:

    理解dp数组存的含义,dp[i][j]代表前i个字符和前j个字符的最长lcs数,dp方程:

    dp[i][j]=dp[i-1][j-1]+1      a[i]==b[j]

    dp[i][j]=max(dp[i][j-1], dp[i-1][j])   a[i]!=b[j]

    如果a[i]=b[j],那么很明显dp[i][j]=dp[i-1][j-1]+1;

    若a[i]!=b[j],我们假设a, b的最大匹配串为c,显然a[i], b[j]不能同时作为c的最后一个字符,那么最优匹配情况即为a[i]为c的最后一个字符或者b[j]为c的最后一个字符(这点不大好理解),即:

    dp[i][j]=dp[i][j-1]    a[i]是c的最后一个字符即匹配的末尾字符

    dp[i][j]=dp[i-1][j]    b[j]是c的最后一个字符即匹配的末尾字符 (其实当a[i], b[j]都不是c的最后一个字符时即a[i], b[j]都不匹配时dp[i][j]=dp[i-1][j-1])

    不等于时即可简写为一个式子dp[i][j]=max(dp[i][j-1], dp[i-1][j])

    输出路径,倒着取出再倒着输出,将正向dp过程搞清楚倒过来理解即可。

    理解好dp代表的含义和搞清楚dp的过程是关键。

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 using namespace std;
     5 const int maxn=1005;
     6 string s1,s2;
     7 char a[maxn];
     8 int p=1,dp[maxn][maxn];
     9 
    10 
    11 void getlen(int len1,int len2)
    12 {
    13     for(int i=1;i<=len1;i++)
    14     {
    15         for(int j=1;j<=len2;j++)
    16         {
    17             if(s1[i]==s2[j])
    18             {
    19                 dp[i][j]=dp[i-1][j-1]+1;
    20             }
    21             else if(dp[i-1][j]>=dp[i][j-1])
    22             {
    23                 dp[i][j]=dp[i-1][j];
    24             }
    25             else
    26             {
    27                 dp[i][j]=dp[i][j-1];
    28             }
    29         }
    30     }
    31 }
    32 
    33 void getlcs(int i,int j)
    34 {
    35         while(i>=1 && j>=1)
    36         {
    37             if(s1[i]==s2[j])
    38             {
    39                 a[p++]=s1[i];
    40                 i--;
    41                 j--;
    42             }
    43             else if(dp[i-1][j]<=dp[i][j-1])//关键:说明之前的最长lcs是在s1[0,i]和s2[0,j-1]中!i本身是一员!不能少! 
    44             {
    45                 j--;
    46             }
    47             else//同理上 
    48             {
    49                 i--;
    50             }
    51         }
    52 }
    53 
    54 int main() 
    55 {
    56     cin>>s1>>s2;
    57     
    58     int len1=s1.length(),len2=s2.length();
    59     for(int i=len1;i>=1;i--) s1[i]=s1[i-1];//后移方便 
    60     for(int i=len2;i>=1;i--) s2[i]=s2[i-1];
    61     
    62     getlen(len1,len2);
    63     getlcs(len1,len2);
    64     for(int i=p-1;i>=1;i--) cout<<a[i];
    65     cout<<endl;
    66     
    67     return 0;
    68 }

    51nod1183编辑距离,与lcs相似的题,只不过想的角度,dp代表含义不一样

    s1[i]==s2[j]时,不用操作,不等时+1,因为不管是增加还是替换都一样操作一步

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=1005;
     7 int dp[maxn][maxn];
     8 string s1,s2;
     9 
    10 void solve(int len1,int len2)
    11 {
    12     for(int i=1;i<=len1;i++)
    13     {
    14         for(int j=1;j<=len2;j++)
    15         {
    16             if(s1[i]==s2[j])//相同不用操作,不同增加一个操作
    17             {
    18                 dp[i][j]=dp[i-1][j-1];
    19             }
    20             else
    21             {
    22                 dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;//dp[i-1][j-1]举个例子就明白 
    23             }                                                           //ab,akscb dp[2][2]=dp[1][1]+1=1; 
    24         }
    25     }
    26 }
    27 
    28 int main()
    29 {
    30     ios::sync)with_stdio(false); cin.tie(0);
    31     
    32     cin>>s1>>s2;
    33     
    34     int len1=s1.length(),len2=s2.length();
    35     for(int i=len1;i>=1;i--) s1[i]=s1[i-1];
    36     for(int i=len2;i>=1;i--) s2[i]=s2[i-1];
    37     for(int i=0;i<=(len1>len2?len1:len2);i++) dp[i][0]=i;
    38     for(int i=0;i<=(len1>len2?len1:len2);i++) dp[0][i]=i;
    39      
    40     solve(len1,len2);
    41     cout<<dp[len1][len2]<<endl;
    42     
    43     return 0;
    44 }

  • 相关阅读:
    Java
    paratest
    ccnet
    资料
    ccnet
    判断类被某个属性应用
    有趣的数学 -- 数学归纳法 -- 互不重叠的单位正方形
    排序算法 -- 堆排序
    APUE CH10 Signals
    APUE CH9 Process Relationship
  • 原文地址:https://www.cnblogs.com/redblackk/p/9557826.html
Copyright © 2011-2022 走看看