/*
【DFS+回溯+字符串】【洛谷P1019】【单词接龙】
https://www.luogu.com.cn/problem/P1019
题意:给你很多个单词 一个开头首字母 每个单词至多用2次 首位相同可以连接 但不能包含
求:组成最长的字符串
分析:
首先处理一下字符串:对于每个字符串,计算出它与剩下字符串的连接性以及连接的个数
然后进行dfs深搜 回溯+维护最大值即可
*/
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
vector<string> vec;
int nums[30][30]={0};
int n,f[30]={0};
char ch;
int dfs(int sum,int idx)
{
int cot=0;
for(int i=0;i<n;i++)
{
if(nums[idx][i]&&f[i]!=2)
{
f[i]++;
cot=max(cot,dfs(vec[i].size()-nums[idx][i],i));//记录最大的数
f[i]--;//回溯
}
}
return sum+cot;
}
void solve()
{
//计算 对于每一个字符串 它在其他字符串的连接性
for(int i=0;i<n;i++)
{ //表示第i个与第j(n-1)个比较连接性
for(int j=0;j<n;j++)
{
//if(i==j) continue; 这里有个小细节 一开始以为本身是完全相同的嘛 想把这个去掉
//但是因为它说:每个单词 可以用最多两次 那么它有可能就调用本身 ee eee
//而不是一开始想的 自己对本身完全覆盖 那么就没必要考虑 结果是给自己挖坑了
for(int z=1;z<vec[i].size();z++)
{
int x=z,y=0;
while(x<vec[i].size()&&y<vec[j].size())
{
if(vec[i][x]!=vec[j][y])
break;
x++;
y++;
}
if(x==vec[i].size())
nums[i][j]=y;
}
}
}
int ans=0;
for(int i=0;i<n;i++)
{
memset(f,0,sizeof(f));
if(vec[i][0]==ch)
{
f[i]++;
ans=max(ans,dfs(vec[i].size(),i));//记录最大值
}
}
cout<<ans;
}
int main()
{
string str;
cin>>n;
for(int i=0;i<n;i++){
cin>>str;
vec.push_back(str);
}
cin>>ch;
solve();
return 0;
}
【DFS+回溯+字符串】【洛谷P1019】【单词接龙】
最新推荐文章于 2024-10-02 23:40:03 发布