zoukankan      html  css  js  c++  java
  • 基础DP(3)

    • 最长公共子序列(LCS)

    放题:

    http://acm.hdu.edu.cn/showproblem.php?pid=1159

    首先,子序列是在给定序列中删去若干元素后得到的序列,例如X=(A,B,C,D,E),那么(A,B,D)就是X的子序列,那(A,B,D)是子串吗?不是,子串的元素在原序列中是连续的。给定两个序列X,Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。最长公共子序列是长度最长的子序列。

    用L[i][j]表示子序列Xi和Yj的最长公共子序列的长度。

    当Xi=Yj时,找X(i-1)和Y(j-1)的最长公共子序列,然后在尾部加上Xi(对于序列长度来说就是+1)。

    当Xi≠Yj时,取X(i-1)和Yj最长公共子序列与Xi和Y(j-1)最长公共子序列的较大值。(所以输出方案时从后往前递推)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int dp[1005][1005];
    string str1,str2;
    
    int LCS(){
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=str1.length();i++){
            for(int j=1;j<=str2.length();j++){
                if(str1[i-1]==str2[j-1])//因为dp[i][j]要通过dp[i-1][j-1]求出,所以i和j从1开始,比较的子序列应该时i-1和j-1
                dp[i][j]=dp[i-1][j-1]+1;//上述的两种情况
                else
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
        return dp[str1.length()][str2.length()];
    }
    int main()
    {
        while(cin>>str1>>str2){
            cout<<LCS()<<endl;
        }
        return 0;
     } 

    要求输出具体方案时,同样可以用滚动数组减少空间复杂度,和0/1背包相同。

     EOF

  • 相关阅读:
    【POJ 2044】 Weather Forecast
    【POJ 1703】 Find them,Catch them
    【SCOI 2005】 骑士精神
    字长与指针
    XModem协议
    SecureCRT乱码问题解决方法
    usb设备驱动程序
    如何检测 51单片机IO口的下降沿
    matlab神经网络工具箱创建神经网络
    九针串口接线问题, 232, 485
  • 原文地址:https://www.cnblogs.com/Untergehen/p/14327843.html
Copyright © 2011-2022 走看看