洛谷 P1278 单词游戏
题意
给定 \(n\) 个字符串(\(n\le 16\)) , 每个字符串都由\(5\)种元音字母组成 , 求最长可以接龙拼接的字符串长度
思路
看到\(n\)的范围 \(+\) 字符串的状态为在/不在 , 考虑状态压缩
设 \(f_{i,j}\)为已接龙状态为\(i\) , 最后字符为\(j\)时的最长长度
首先考虑是否可以递增着往上\(dp\)呢 ? 显然是可以的 , 设\(sta\)为状态 , 那么每次\(sta++\)就行
代码
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int ans = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
ans = ans * 10 + ch - '0';
ch = getchar();
}
return ans * f;
}
const int N = 19;
int f[1<<N][N];
string s;
int a[N];
char b[N],c[N];
int ans = 0;
int main() {
int n =read();
for (int i =1;i<=n;i++) {
cin>>s;
a[i] = s.size();
b[i] = s[s.size()-1];
c[i] = s[0];
}
f[0][0] = 0;
int p = 2;
int s = 1;
for (int i =1; i<= n; i++) {
f[1<<i-1][i] = a[i];
}
for (int i = 3; i<1<<n;i++) {
while (i >= 1<<p) p++;
for (int j = 1; j<= p;j++) {
if (i&1<<j-1) {
s = i^1<<j-1;
for (int l = 1; l<= p;l++) {
if (!(s&1<<l-1) || b[l]!=c[j])continue;
f[i][j] = max(f[i][j],f[s][l] + a[j]);
ans = max(ans,f[i][j]);
}
}
}
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号