程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> ZOJ 1953 Advanced Fruits(LCS)

ZOJ 1953 Advanced Fruits(LCS)

編輯:C++入門知識

題意:給出兩個字符串,求能滿足子串(可以不連續)中包含給出的兩個字符串的最短字符串.

思路:本質上就是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 
#include 
#include 
#include 
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;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved