正题
luogu 1019
题目大意
给你若干个词语,让你把他们连起来(重复段叠在一起),每个词语最多用两次,问你该串最长是多少
解题思路
dfs枚举一个单词后面接哪个单词,然后枚举重叠长度,再用hash判断是否相同
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 200
using namespace std;
int n, ans, l[N], p[N];
unsigned long long pw[N], hs[N][N];
char s[N][N];
void dfs(int x, int sum)
{ans = max(ans, sum);for (int i = 1; i <=n; ++i){if (p[i] == 2) continue;int g = 0;for (int len = 1; len <= min(l[x], l[i]) - 1; ++len){int j = l[x] - len;if (hs[x][l[x]] - hs[x][j] * pw[len] == hs[i][len])//判断是否相等{g = len;//最短的长度break;}}if (g){p[i]++;//记录使用次数dfs(i, sum + l[i] - g);p[i]--;}}return;
}
int main()
{scanf("%d", &n);pw[0] = 1;for (int i = 1; i <= 1000; ++i)pw[i] = pw[i - 1] * 131;for (int i = 1; i <= n; ++i){scanf("%s", s[i]+1); l[i] = strlen(s[i]+1);hs[i][0] = 0;for (int j = 1; j <= l[i]; ++j)hs[i][j] = hs[i][j - 1] * 131 + s[i][j];}scanf("%s", s[0]+2);s[0][1] = '/';l[0] = strlen(s[0]+1);hs[0][0] = 0;for (int j = 1; j <= l[0]; ++j)hs[0][j] = hs[0][j - 1] * 131 + s[0][j];dfs(0, 1);printf("%d", ans);return 0;
}