POJ 1458 最长公共子序列的长度

深入理解数据库原理
以实战为基础,以数据库原理为基础,结合实战,深入理解数据库原理。
wangxiaoming

                                            最长公共子序列的长度

题目链接 :点击打开链接


   由于昨天 没有写博客 ,没有总结 ,这是对自己的极端不负责任, 必须对自己足够狠,足够用功, 才能改变自己的命运

   今天补上,并且保持今天的任务量!

   题目大意: 

         子序列是,是一个序列中抽出几个元素后剩下的元素序列, 一个序列 X1 X2 X3 ....XN另一个序列 Z1 Z2 ...ZK 是X 的一个子序列, 如果存在一个严格的递增序列, 例如    序列 Z< A B F C >是 序列X < A B C F B C >在下标1 2 4 6 ,给出两个子序列  X , Y  求出  两个序列的最大公共子序列的长度

   输入:

         程序的输入来自标准输入,每个输入包含两个输入字符串  表示两个序列,两个序列之间 以空格分开,输入正确

   输出:

        对于每一个输出 每一行输出最大公共子序列的长度;

解题思路 : 标准的求最大公共子序列问题, 典型的动态规划问题,关键在于找到 动态方程:

              思路 :  

                1、如果两个子序列 : X1 X2 .... XN   

                                                 Y1 Y2 .....YN  

                   Xi = Yi    那么设 dp[i][j]   表示的是x 第 i 个 和 y 的第 j 个 的最大公共子序列的个数, 由于  Xi Yj相等,那么计算xi-1 , yj-1 dp[i][j]  = dp[i-1][j-1] +1

               2、 不相等 那么 dp[i][j] = max(dp[i-1][j] , dp[i][j-1])也就是说  如果 xi ,yj 不相等 那么计算子问题 xi , yj-1, 最大公共序列的,或者xi-1, yj 的最大
               3、 对于最开始设置的值肯定是0 因为对于最开始是没有公共子序列的

               先贴一个 没有A过的:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define  Max 500

int dp[Max][Max];

int main()
{

    char  str1[Max], str2[Max];
    int len1, len2;
    while(scanf("%s %s",str1,str2))
    {
        memset(dp, 0, sizeof(dp));
        len1 = strlen(str1);//返回的就是字符串的长度
        len2 = strlen(str2);
        for(int i = 1; i <= len1; i++)
        {
            for(int j = 1 ; j <= len2; j++)
            {
                if(str1[i-1] == str2[j-1])
                {//这里为什么是 先判断i-1 呢,因为最多就是str【i -1】
                    //如果i= 1 那么就是第0 个相等
                    dp[i][j] = dp[i-1][j-1] + 1;
                }
                else
                {
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        cout<<dp[len1][len2]<<endl;
    }
    return 0;
}
上面没有A掉是因为超出时间限制

下面给出一个A掉的 每次if else 一下肯定多出一些步骤 , 复杂度增加因此没有A掉  下面是点击打开链接 大神代码 : 这里借鉴下。。。。不过思想是一样的

下面其实向判断 s1[i-1] s2[i-1] 用一个单独的函数来进行判断了,并且每次 返回的是三个数的最大值。。。。很简洁,表示很膜拜。。。。

#include <iostream>
using namespace std;
#define MAXV 1000

int same(int a,int b){
	return a==b?1:0;
}

int max(int a,int b, int c){
	if(a>=b && a>=c) return a;
	if(b>=a && b>=c) return b;
	return c;
}

int dp[MAXV][MAXV];
char s1[MAXV],s2[MAXV];

int main(){
	int len1,len2,i,j;

	while(scanf("%s %s",s1,s2)!=EOF){
		memset(dp,0,sizeof(dp));

		len1=strlen(s1);
		len2=strlen(s2);

		for(i=1;i<=len1;i++){
			for(j=1;j<=len2;j++){
				dp[i][j]=max( dp[i-1][j-1]+same(s1[i-1],s2[j-1]) , dp[i-1][j] , dp[i][j-1]);
			}
		}

		printf("%d\n",dp[len1][len2]);
	}
	return 0;
}


wangxiaoming CSDN认证博客专家 架构 Spring Boot Redis
博客是很好的总结和记录工具,如果有问题,来不及回复,关注微信公众号:程序员开发者社区,获取我的联系方式,向我提问,也可以给我发送邮件,联系 1275801617@qq.com
©️2020 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值