您的位置:首页 > 其它

hpu暑假训练【最长公共子序列&&回溯输出】

2017-08-08 17:12 316 查看
/*
LCS

输入BDCABA    ABCBDAB求最长公共子序列并输出这个子序列
子串:连续
子序列:可以不连续
dp[i][j]//第一个字符串在第i个字符前且第二个串在第j个字符前可构成的最长子序列的长度

dp[i][j] = 			0  						i=0 || j=0
dp[i-1][j-1]+1    		 str1[i]==str2[j]
max(dp[i-1][j],dp[i][j-1])	 str1[i]!=str2[j]
*/
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
int main()
{
char str1[20];
char str2[20];
scanf ("%s %s",str1+1,str2+1);
str1[0] = str2[0] = '0';
int l1 = strlen(str1)-1;
int l2 = strlen(str2)-1;
int dp[20][20] = {0};//0  						i=0 || j=0

for (int i = 1 ; i <= l1 ; i++)
{
for (int j = 1 ; j <= l2 ; j++)
{
if (str1[i] == str2[j])//dp[i-1][j-1]+1    		 str1[i]==str2[j]
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);//max(dp[i-1][j],dp[i][j-1])	 str1[i]!=str2[j]
}
}

//回溯求LCS
int pos1 = l1;
int pos2 = l2;
stack<char> S;
while (pos1 > 0 && pos2 > 0)
{
if (str1[pos1] == str2[pos2])
{
S.push(str1[pos1]);
pos1--;
pos2--;
}
else if (dp[pos1-1][pos2] > dp[pos1][pos2-1])
pos1--;
else
pos2--;
}
while (!S.empty())
{
printf ("%c%c",S.top(),(S.size() == 1) ? '\n' : ' ');
S.pop();
}
printf ("%d\n",dp[l1][l2]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐