HDU1159(dp最长公共子序列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159

Common Subsequence

Problem Description

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, xij = 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.
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. 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
题目大意:题意很简单,就是给你两个字符串,求他们两个的最长公共子序列。
解题思路:比赛时遇到的一道题,硬是没憋出来。自己的动态的规划这方面还是很渣,看的懂题解却用不来。下来好好学习了别人的方法,这题属于dp中比较基础的题。代码也很短,但思路却很不错,想通了就觉得很妙,想不通就很难受。

在这里插入图片描述
用一个二维数组来存储最大公共子序列的长度,一个双重循环,来遍历两个串。当遇到相同字符时就把就将图中该位置左上角的数加一赋给当前位置。如果不相同就比较i-1和j-1位置的值,保留最大的赋给当前位置。这样一直递推到两个字符串结束,最后一个位置存的必定为最长。

#include<cstdio>
#include<cstring>
int Max(int x, int y)
{
    if(x > y)
        return x;
    else
        return y;
}
int main()
{
    int dp[500][500];
    char a[500];
    char b[500];

    while(~scanf("%s%s", a, b))
    {
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < strlen(a) + 1; ++i)
            for(int j = 0; j < strlen(b) + 1; ++j)
            {
                if(i == 0 || b == 0)
                    continue;
                if(a[i - 1] == b[j - 1])
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                else
                    dp[i][j] = Max(dp[i - 1][j], dp[i][j - 1]);
            }
         /*   for(int i = 0; i <= strlen(a) + 1; ++i)
            {
                for(int j = 0; j <= strlen(b) + 1; ++j)
                    printf("%d ", dp[i][j]);
                printf("\n");
            }*/
            printf("%d\n", dp[strlen(a)][strlen(b)]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值