【DFS+回溯+字符串】【洛谷P1019】【单词接龙】

传送门

/*
	【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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值