一道深搜题
应该很早就做然而并没有
然后需要注意一下
- 相邻的两部分不能存在包含关系就是说如果存在包含关系,就不能标记为使用过。
- 每个单词最多出现两次
这样提前先预处理一下每两个单词之间的重复部分
用sam[i][j]表示第i个单词后接第j个单词的重叠的部分
然后dfs,记得用vis标记一下该单词使用过几次
#include<cstdio> #include<iostream> #define sev en using namespace std; int n,ans,ret; string a[30]; char ch; int vis[30],sam[30][30]; int find(int x,int y){ bool f = 1; int cnt = 0; for(int i = a[x].size() - 1;i >= 0;i--){//前一个从后开始 for(int j = i;j < a[x].size();j++) if(a[x][j] != a[y][cnt++]){//后一个从前开始 f = 0; break; } if(f == 1) return a[x].size() - i;//重叠部分 cnt = 0; f = 1; } return 0;//一直没找到qaq } void dfs(int x){ bool f = 0; for(int i = 1;i <= n;i++){ if(vis[i] >= 2) continue;//只能用两次 if(sam[x][i] == 0) continue; if(sam[x][i] == a[x].size() || sam[x][i] == a[i].size())//包含关系就跳 continue; ans += a[i].size() - sam[x][i]; vis[i]++; f = 1; dfs(i); ans -= (a[i].size() - sam[x][i]); vis[i]--;//常规操作 } if(f == 0) ret = max(ret,ans);//记录最大 return ; } int main(){ scanf("%d",&n); for(int i = 1;i <= n;i++) cin >> a[i];//cin很慢尽管很方便www最好别用 我为什么用了这件事不要在意 cin >> ch; for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) sam[i][j] = find(i,j);//预处理 for(int i = 1;i <= n;i++) if(a[i][0] == ch){//找开头 vis[i]++; ans = a[i].size(); dfs(i); vis[i] = 0; } printf("%d",ret);//完成辽~ return 0; }
itsomethingood
果然我太菜了
深搜好难啊啊啊啊
orz我jio的我能被搜索搞si
原文地址:https://www.cnblogs.com/sevenyuanluo/p/10779584.html
时间: 2024-10-11 06:59:59