递推专题(补发)

H - 最长公共子序列Lcs

给出两个字符串A B,求A与B的最长公共子序列(A,B的长度 <= 1000,子序列不要求是连续的)。

比如两个字符串为:

A:abcicba B:abdkscab

ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。。

Input

第1行:字符串A 第2行:字符串B

Output

输出最长的子序列,如果有多个,随意输出1个。

Sample

InputOutput
abcicba
abdkscab
abca

 dp数组的递推有两种情况

1.当前对应的字母相等那么就为dp[i-1][t-1]+1,就是在这个相等字母前的最大公共长度+1

2.当前字母不相等就是在dp[i][t-1]和dp[i-1][t]中寻找最大值

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=1010;
int dp[maxn][maxn],sign[maxn][maxn];//dp数组记录公共序列长度;sign数组做标记用于后面输出时递归
char a[maxn],b[maxn];
void myprintf(int m,int n)
{
	if (m<1||n<1) {
		return;
	}
	if (sign[m][n]==0) {
		myprintf(m-1,n-1);
		cout<<a[m-1];
	} else if (sign[m][n]==1) {
		myprintf(m-1,n);
	} else {
		myprintf(m,n-1);
	}
}
int main()
{
	int i,t,m,n;
	cin>>a>>b;
	m=strlen(a);
	n=strlen(b);
	for (i=1;i<=m;i++) {
		for (t=1;t<=n;t++) {
			if (a[i-1]==b[t-1]) {
				dp[i][t]=dp[i-1][t-1]+1;
				sign[i][t]=0;
			} else if (dp[i-1][t]>dp[i][t-1]) {
				dp[i][t]=dp[i-1][t];
				sign[i][t]=1;
			} else {
				dp[i][t]=dp[i][t-1];
				sign[i][t]=2;
			}
		}
	}
	myprintf(strlen(a),strlen(b));
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值