• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
PTA-两个字符串的所有最长公共子序列

7-27 两个字符串的所有最长公共子序列

分数 15

求两个字符串的所有最长公共子序列。

输入格式:

输入长度≤100的两个字符串。

输出格式:

输出两个字符串的所有最长公共子序列,若最长公共子序列多于1个,则将所有子序列按字典序从小到大排序后输出。

输入样例1:

ABCBDAB
BDCABA

输出样例1:

BCAB
BCBA
BDAB

输入样例2:

ABACDEF
PGHIK

输出样例2:

NO

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

思路

设\(dp[i][j]\)表示对于字符串\(a\)的前i个字符和字符串\(b\) 的前j个字符,构成最长公共子序列的长度

\(\begin{equation} dp[i][j]=\left\{ \begin{aligned} max(dp[i - 1][j],dp[i][j - 1])\quad a[i] != a[j]\\ dp[i - 1][j - 1] + 1\quad a[i] = a[j]\\ \end{aligned} \right . \end{equation}\)

回溯

我们从\(dp[n][m]\)开始考虑,若当前第\(n\)位和第\(m\)位相等,那么这一位一定是LCS的一位,我们把状态递推到\(n - 1, m - 1\), 若这两位不相等,则比较\(dp[n - 1][m]\)和\(dp[n][m - 1]\)的大小,若不相等选择序列较长的进行递推,若相等则将问题划分为两个问题,递归求解。

Code

#include <iostream>
#include <cstring>
#include <vector>
#include <set>
using namespace std;

/*
	dp[i][j] 表示 a串长度为i b串长度为j的最长公共子序列
	dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] + 1);
	aabcc 
	abcc
*/
char a[110], b[110];
int dp[110][110], n, m;
set<string> s1;

void go_back(int i, int j, string str) {
	while(i >= 1 && j >= 1) {	
		if(a[i] == b[j]) {
			str = a[i] + str;
			i --, j --;
		} else {
			if(dp[i - 1][j] > dp[i][j - 1]) {
				i --;
			} else if(dp[i - 1][j] < dp[i][j - 1]) {	
				j --;
			} else{
				go_back(i - 1, j, str);
				go_back(i, j - 1, str);
				return;
			}
		}
	}
	if(str.length()) s1.insert(str);
}

int main() {	
	cin >> (a+1) >> (b+1);
	n = strlen(a+1), m = strlen(b+1);
	for(int i = 1; i <= n; i ++) {
		for(int j = 1; j <= m; j ++) {
			dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
			if(a[i]==b[j]) dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
		}
	}

	for(int i = 1; i <= n; i ++) {
		for(int j = 1; j <= m; j ++) {
			cout << dp[i][j] << " \n"[j == m];
		}
	}

	go_back(n, m, "");
	for (auto &x: s1) {
		cout << x << "\n";
	}
}
posted on 2023-01-11 19:58  Jack404  阅读(176)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3