dfs
刚开始卡了一段
纠结怎么用字符串添加再回溯
确实没啥思路
后来发现把题目完全转换为可以后接的数字矩阵就会简单很多
然后dfs
对我而言dfs的本质是
先写生成全排列的框架
然后加上判定条件和回溯
即可解决问题
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 2e1 + 10;
int prefix[MAXN][MAXN] = {0}, used[MAXN] = {0};
int N, ans = 0;
string mode[MAXN];
void preoprt(int x, int y) //预处理
{
int lena = mode[x].length() - 1, lenb = mode[y].length() - 1;
for(int i = 0; i < lenb; i++)
{
if(mode[y][i] == mode[x][lena]) //寻找后串里每一个等于前串最后一个的字符
{
bool flag = true;
if(lena > i) //如果包含就舍去
{
for(int j = i; j >= 0; j--)//判断是否能从该位向前拼接
{
if(mode[x][lena - j] != mode[y][i - j])
flag = false;
}
if(flag)
{
prefix[x][y] = lenb - i; //构建二维拼接数组 prefix[a][b] 存a接b应加长度
goto l1;
}
}
}
}
l1:
return ;
}
void dfs(int ret, int len)
{
used[ret]++;
ans = max(ans, len); //寻值
for(int i = 0; i < N; i++)
{
if(used[i] <= 1 && prefix[ret][i] > 0)
{
dfs(i, len + prefix[ret][i]);
used[i] --; //回溯
}
}
}
int main()
{
cin>>N;
char head;
for(int i = 0; i < N; i++)
cin>>mode[i];
cin>>head;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
preoprt(i, j);//预处理
}
}
for(int i = 0; i < N; i++)
{
dfs(i, mode[i].length());
}
cout<<ans<<endl;
return 0;
}