题目大意
对于字符串 $a,b$,若 $a$ 的末尾与 $b$ 的开头有部分字符串相同,则其可以拼接起来。例如 at + tact = atact。
给定词典和初始字母,每个单词最多出现两次,求最大拼接长度。
分析
我是没想出来,经题解提示了拼接函数才写出来的。
设 $mt(x,y)$ 为第 $x$ 和 $y$ 个单词拼接后的最小重合长度,其可简单的通过匹配得到。
char s[30][100];
ll len[30];
ll mt[30][30];
void init(int x, int y) {
ll ml = min(len[x], len[y]) - 1;
for (ll i = 1; i <= ml; i++) {
int flag = 1;
for (ll j = 0; j <= i - 1; j++) {
if (s[x][len[x] + j - i] != s[y][j]) {
flag = 0;
break;
}
}
if (flag) {
mt[x][y] = i;
break;
}
}
}
然后回溯 dfs,搜索即可。
ll n;
int vis[30];
ll dfs(int x) {
if (vis[x] >= 2)
return 0;
vis[x]++;
ll maxlen = 0;
for (ll i = 1; i <= n; i++) {
if (mt[x][i] > 0) {
maxlen = max(maxlen, dfs(i) - mt[x][i]);
}
}
vis[x]--;
return maxlen + len[x];
}
int main() {
n = rr();
for (ll i = 1; i <= n; i++) {
scanf("%s", s[i]);
len[i] = strlen(s[i]);
}
for (ll i = 1; i <= n; i++) {
for (ll j = 1; j <= n; j++) {
init(i, j);
}
}
ll maxlen = 0;
scanf("%s", s[0]);
for (ll i = 1; i <= n; i++) {
if (s[i][0] == s[0][0]) {
maxlen = max(maxlen, dfs(i));
}
}
printf("%lld\n", maxlen);
return 0;
}