【旅行】题解

Link

题目大意,求出最长公共子序列(拉出序列(多个))。

分析:先用 dp 求出长度 l e n len len。接下来用搜索拉出序列。
注意:若两个串相同,则它们尾部相等(显然)。
所以定义 r a [ i ] [ j ] ra[i][j] ra[i][j] 为在 s1 中,前 i i i 个字符中字符为 j + ′ 0 ′ j+'0' j+0 的最大下标。 r b [ i ] [ j ] rb[i][j] rb[i][j] 同理。
那么有:

for(int i = 1;i <= n1; i++) // 下标
	    for(int j = 0;j < 26; j++) // 'a'~'z'
	        if(c1[i] == char('a' + j)) ra[i][j] = i; 
	        else ra[i][j] = ra[i - 1][j];

我们要找子串,因为其字符分别相同,所以 j j j 相等,分别寻找 i i i 即可。
在搜索的角度思考:传入参数 x x x, y y y, l e n len len, c c c。分别表示 s1的前 x x x 个字符,s2的前 y y y 个,子串还剩的长度,目前的子串。

枚举字符 k k k,找到其在两字符串中的最后位置 t 1 t1 t1 t 2 t2 t2,当 s 1 [ 1... t 1 ] s1[1...t1] s1[1...t1] s 2 [ 1... t 2 ] s2[1...t2] s2[1...t2] 中有长度为 l e n len len 的相同子串时,就往前搜索。

l e n len len 0 0 0,说明已经查找到一个解,存入 string 数组,输出时排序即可。

void dfs(int x, int y, int len, string c) {
	if(!len) {
		s[++sum] = c;
		return ;
	}
	for(int k = 0;k < 26; ++k) {
		int t1 = ra[x][k], t2 = rb[y][k];
		if(dp[t1][t2] == len) {
			dfs(t1 - 1, t2 - 1, len - 1, char(k + 'a') + c); // 当前字符在存入子串		
		}
	}
}
posted @   LCat90  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示