51Nod 1006 最长公共子序列LCS DP水题

题目链接:51 Nod 1006
题意: 求A,B的最长公共子序列并输出。
分析:先求出最长公共子序列的长度,然后再根据最长公共子序列的长度逆序求出最长公共子序列。

#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;

//#pragma comment(linker, "/STACK:1024000000,1024000000")

#define FIN             freopen("input.txt","r",stdin)
#define FOUT            freopen("output.txt","w",stdout)
#define fst             first
#define snd             second
#define lson            l, mid, rt << 1
#define rson            mid + 1, r, rt << 1 | 1

typedef __int64  LL;
//typedef long long LL;
typedef unsigned int uint;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int MAXN = 1000 + 5;
const int MAXM = 600 + 5;

char A[MAXN], B[MAXN];
int dp[MAXN][MAXN];
char R[MAXN];

int main() {
#ifndef ONLINE_JUDGE
    FIN;
#endif // ONLINE_JUDGE
    while (~scanf("%s %s", A, B)) {
        memset(dp, 0, sizeof(dp));
        int lenA = strlen(A);
        int lenB = strlen(B);
        for (int i = 0; i < lenA; i++) {
            for (int j = 0; j < lenB; j++) {
                if (A[i] == B[j]) {
                    if (i == 0 || j == 0) dp[i][j] = 1;
                    else dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    if (i == 0 && j == 0) dp[i][j] = 0;
                    else if (i == 0) dp[i][j] = dp[i][j - 1];
                    else if (j == 0) dp[i][j] = dp[i - 1][j];
                    else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        // printf("%d\n", dp[lenA - 1][lenB - 1]);
        int temp = dp[lenA - 1][lenB - 1];
        R[temp] = '\0';
        for (int i = lenA - 1; i >= 0; i--) {
            if (!temp) break;
            for (int j = lenB - 1; j >= 0; j--) {
                if (A[i] == B[j] && dp[i][j] == temp) {
                    R[--temp] = A[i];
                    break;
                }
            }
        }
        puts(R);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值