首页 > 其他 > 详细

ZOJ 1953 Advanced Fruits(LCS)

时间:2014-04-08 05:37:51      阅读:501      评论:0      收藏:0      [点我收藏+]

题意:给出两个字符串,求能满足子串(可以不连续)中包含给出的两个字符串的最短字符串.

思路:本质上就是LCS问题,做法是先找出两个串的LCS,并记录其位置

设dp[i][j]为A串以第i个字符结尾B串以第j个字符结尾的LCS, 用path数组来记录路径,

如果A[i] == B[j] 那么dp[i][j] = dp[i - 1][j - 1].

否则 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) .

用两个数组pos1, pos2分别代表LCS在各自串中的位置.

那么不是LCS的字符就要按照一定的顺序打印,详细的看代码吧

#include <cstdio>
#include <string>
#include <iostream>
#include <memory.h>
using namespace std;
const int MAX = 128;

int dp[MAX][MAX];
int pos1[MAX], pos2[MAX], cnt;
char path[MAX][MAX];
char f1[MAX], f2[MAX];

void traverse(int i, int j){
	if(i == 0 || j == 0)return;
	if(path[i][j] == 0){
		traverse(i - 1, j - 1);
		pos1[cnt] = i;
		pos2[cnt++] = j;
	}else if(path[i][j] == 1){
		traverse(i - 1, j);
	}else{
		traverse(i, j - 1);
	}
}

int main(int argc, char const *argv[]){
	while(scanf("%s%s", f1 + 1, f2 + 1) == 2){
		memset(dp, 0, sizeof(dp));

		int len1 = strlen(f1 + 1), len2 = strlen(f2 + 1);
		for(int i = 1; i <= len1; ++i){
			for(int j = 1; j <= len2; ++j){
				if(f1[i] == f2[j]){
					dp[i][j] = dp[i - 1][j - 1] + 1;
					path[i][j] = 0;
				}else if(dp[i - 1][j] > dp[i][j - 1]){
					dp[i][j] = dp[i - 1][j];
					path[i][j] = 1;
				}else{
					dp[i][j] = dp[i][j - 1];
					path[i][j] = 2;
				}
			}
		}

		cnt = 1;
		traverse(len1, len2);
		pos1[cnt] = len1 + 1;
		pos2[cnt++] = len2 + 1;
		for(int i = 1; i < cnt; ++i){
			for(int j = pos1[i - 1] + 1; j < pos1[i]; ++j){
				printf("%c", f1[j]);
			}
			for(int j = pos2[i - 1] + 1; j < pos2[i]; ++j){
				printf("%c", f2[j]);
			}
			if(i != cnt - 1)
				printf("%c", f1[pos1[i]]);
		}
		printf("\n");
	}
	return 0;
}


ZOJ 1953 Advanced Fruits(LCS),布布扣,bubuko.com

ZOJ 1953 Advanced Fruits(LCS)

原文:http://blog.csdn.net/zxjcarrot/article/details/23130253

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!