【旅行】题解
题目大意,求出最长公共子序列(拉出序列(多个))。
分析:先用 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); // 当前字符在存入子串
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现