基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
Problem Description:
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
比如两个串为:
abcicba
abdkscab
ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。
Input
第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)
Output
输出最长的子序列,如果有多个,随意输出1个。
Input示例
abcicba
abdkscab
Output示例
abca
思路: 正常的LCS + 记录路径就好了
废话不多说直接上代码:
AC代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
#define MAXN 1000 + 10
int dp[MAXN][MAXN], vis[MAXN][MAXN];
char s1[MAXN], s2[MAXN], ans[MAXN];
int cnt = 0;
void path(int i, int j)//定一个函数从最后到开头找所走的路径
{
while(i > 0 && j > 0)
{
if(vis[i][j] == 0)
{
ans[cnt++] = s1[i - 1];
j--; i--;
}
else if(vis[i][j] == 1)
{
j--;
}
else
i--;
}
}
int main()
{
int k = 0;
memset(dp, 0, sizeof(dp));
scanf("%s%s", s1, s2);
int len1 = strlen(s1), len2 = strlen(s2);
for(int i = 1; i <= len1; i++)
{
for(int j = 1; j <= len2; j++)
{
if(s1[i - 1] == s2[j -1])
{
dp[i][j] = dp[i - 1][j - 1] + 1;
vis[i][j] = 0;//来自左上方的
}
else
{
if (dp[i - 1][j] < dp[i][j - 1])
{
dp[i][j] = dp[i][j - 1];
vis[i][j] = 1;//来自左边
}
else
{
dp[i][j] = dp[i - 1][j];
vis[i][j] = -1;//来自上边
}
}
}
}
path(len1, len2);
for(int i = cnt - 1; i >= 0; i--)//倒序输出
printf("%c", ans[i]);
printf("\n");
return 0;
}
我喜欢程序员,他们单纯、固执、容易体会到成就感;
面对压力,能够挑灯夜战不眠不休;
面对困难,能够迎难而上挑战自我。
他们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。
我想说的是,其实我是一只程序猿*
–唐尤华