POJ-1458-最长公共子序列

原题
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, …, xm > another sequence Z = < z1, z2, …, zk > is a subsequence of X if there exists a strictly increasing sequence < i1, i2, …, ik > of indices of X such that for all j = 1,2,…,k, x ij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
Input
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.
Output
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
题意:
输入两个字符串s1,s2,寻找两个字符串中的最大公共子序列s,(从中按字符串本身的顺序提取出的子序列,但是该字符之间在原字符串中不必非要连续)
例如:第一个样例:
s1中提取出的abfc
s2中也提取出abfc
题解:
这道题目要利用动态规划,设置一个dp[i][j],里面的元素储存的是s1中第i元素之前与s2中的第j个元素之前可以提取出的最长公共子序列的长度。
状态转移方程:

               if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1;//如果两个字符相等,则在其dp[i-1][j-1]上加一,因为需要消耗掉s1的第i个字符和s2的第j个字符
            else
            {
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);//若是不相等,则继承dp[i-1][j]和dp[i][j-1]中较大,
                //前者是没有消耗s1中的第i个字符时的最大长度,后者是没有消耗掉s2中的第j个字符时的最大长度,取两者中较大的一个
            }

附上AC代码:

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int dp[1100][1100];//dp[i][j]记录s2的前j个字符与s1的前i个字符中相同的个数
string s1,s2;
int l1, l2;//记录字符串的长度
int max(int a,int b)//定义max函数
{
    return a>b?a:b;
}
int main()
{
    while(cin>>s1>>s2)
    {
        l1=s1.length();
        l2=s2.length();
        memset(dp,0,sizeof(dp));//初始化
        for(int i=1;i<=l1;++i)
        {
            for(int j=1;j<=l2;++j)
            {
                if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1;//如果两个字符相等,则在其dp[i-1][j-1]上加一,因为需要消耗掉s1的第i个字符和s2的第j个字符
                else
                {
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);//若是不相等,则继承dp[i-1][j]和dp[i][j-1]中较大,
                    //前者是没有消耗s1中的第i个字符时的最大长度,后者是没有消耗掉s2中的第j个字符时的最大长度,取两者中较大的一个
                }
            }
        }
        cout<<dp[l1][l2]<<endl;//输出遍历完所有的i和j的最大长度
    }
    return 0;
}

欢迎评论!

猜你喜欢

转载自blog.csdn.net/wjl_zyl_1314/article/details/83002116