最近在做 关于 搜索 的练习。AC了这道题 就来 写题解了。
首先,我们可以 用一个dis的 二维数组 来储存 每一对 字符串 中首尾相同 的 字符串 的个数。
(对于测试样例,dis[3][2]=2,而dis[2][3]=0。)
(字符串的 预处理 这里 我搞了 一段时间,建议 读者也去 实践一下)。
处理出来 dis数组后 剩下的 就很好办了,可以 纯枚举深搜。
以每一个 字符串 为起点,将它尝试 与 每个 还没有 被vis标记过的 字符串 相连。step用来 记录 总步数。
这里 有一个 小 减枝。设 我们 目前 已经求到的 最优解 为 ans。如果 当前 的 step已经 大于了ans,则可以直接return。
具体实现见代码。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define N 20
#define inf 0x7f7f7f7f
string a[N];
int T,ans=inf,n,dis[N][N],vis[N];
int _oper(int x,int y) {
int sum=0,len1=a[x].length(),len2=a[y].length(),len=min(len1,len2);
for(int l=0;l<len;l++) {
int flag=0;
for(int i=0;i<=l;i++)
if(a[x][len1-i-1]!=a[y][l-i]) {
flag=1;
break;
}
if(!flag) sum=l+1;
}
return sum;
}
void dfs(int step,int now,int k) {
if(k==n) {
ans=min(ans,step);
return ;
}
if(step>ans) return ;
for(int i=1;i<=n;i++) {
if(vis[i]) continue;
vis[i]=1;
dfs(step+a[i].length()-dis[now][i],i,k+1);
vis[i]=0;
}
}
int main() {
cin>>T;
while(T--) {
ans=inf;
memset(dis,0,sizeof(dis));
cin>>