hdu 1159

题目概述

给定两个无空白字符的字符串a,b,求其最长公共子序列的长度

时限

1000ms/2000ms

输入

每行两个字符串a,b,输入到EOF为止

限制

没有限制

输出

每行一个数,最长公共子序列的长度

样例输入

abcfbc abfcab
programming contest
abcd mnp

样例输出

4
2
0

讨论

dp的最长公共子序列,有公式,但额不太理解
这里写图片描述
意思就是开一个二维数组,将两个字符串各从下标为1的位置摆开,下标0的位置作为基准位置留空,之后对每个位置所在行列对应的字符比较,相同则取左上位置的数+1,否则取左侧和上侧两个位置中较大的值
之所以开二维数组,是求序列的时候方便,但若仅仅求其长度,一维足矣,只要把左上的数单独记录下来即可

题解状态

31MS,1720K,798B,C++

题解代码

#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<stack>;
using namespace std;
#define INF 0x3f3f3f3f
#define maxx(a,b) ((a)>(b)?(a):(b))
#define minn(a,b) ((a)<(b)?(a):(b))
#define MAXN 1003
#define memset0(a) memset(a,0,sizeof(a))

char a[MAXN], b[MAXN];
int dp[MAXN];//处理用的二维数组被压缩成一维
int fun()
{
    int lena = strlen(a), lenb = strlen(b);//记下字符串长度用于控制循环
    for (int p = 1; p <= lena; p++) {
        int leftup = 0;//记录每行左上位置的数值 这个位置初始一定是0 因为列下标是0
        for (int o = 1; o <= lenb; o++) {//空出0下标位置 从1开始
            int up = dp[o];//记录上方的值 因为每个次填入新数后这个位置便被覆盖 所以要提前记录
            if (a[p - 1] == b[o - 1])//公式的两种情况
                dp[o] = leftup + 1;
            else
                dp[o] = maxx(dp[o], dp[o - 1]);
            leftup = up;//对于下一个数 现在的正上方便是其左上方
        }
    }
    return dp[lenb];
}
int main(void)
{
    //freopen("vs_cin.txt", "r", stdin);
    //freopen("vs_cout.txt", "w", stdout);

    while (~scanf("%s%s", a, b)) {//input
        printf("%d\n", fun());//output
        memset0(dp);
    }
}

EOF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值