1. 程式人生 > >dfs | 洛谷 | P1019

dfs | 洛谷 | P1019

https://www.luogu.org/problemnew/solution/P1118

  1. 用mt函式求每兩個單詞的最小重合部分(越小越好)
  2. dfs的for內夾緊模式 https://www.cnblogs.com/TQCAI/p/8523035.html
#include <bits/stdc++.h>
#define FF(a,b) for(int a=0;a<b;a++)
#define F(a,b) for(int a=1;a<=b;a++)
#define LEN 30

using namespace std;

string tr[LEN]
;//儲存字串 int yc[LEN][LEN];//yu chuli 兩個字母的最小重疊部分 int n; char ch;//開頭字母 int vis[LEN]; int an=0;//每次搜尋到的最長串 int ans=0; void dfs(int p){//以p編號單詞為尾部 bool jx=false; F(i,n){ //遍歷所有單詞序列 if(vis[i]>=2) continue;//最多使用兩次 if(yc[p][i]==0) continue;//兩個單詞沒有重合部分 if(yc[p][i]==tr[p].size() || yc[
p][i]==tr[i].size()) continue;//有包含關係 an += (tr[i].size()-yc[p][i]);//兩單詞合併再減去最小重合部分 vis[i]++;//使用了一次 jx=true; dfs(i); an -= (tr[i].size()-yc[p][i]);//兩單詞合併再減去最小重合部分 vis[i]--; } if(jx==false){//說名沒有任何一個單詞可以相連,走到了遞迴盡頭 ans=max(ans,an); //更新ans
} } //min together int mt(int x,int y){ //mt函式, 返回x單詞後y的最小重疊部分 for(int i=tr[x].size()-1;i>=0;i--){//從尾部向前掃描 int iy=0; bool fd=true; for(int ix=i;ix<tr[x].size();ix++){ if(tr[x][ix]!=tr[y][iy++]){ fd=false; break; } } if(fd==true){ return tr[x].size()-i; } } return 0; } int main(){ // freopen("./in","r",stdin); cin>>n; F(i,n){ cin>>tr[i]; } cin>>ch; F(i,n)F(j,n){ //預處理yc yc[i][j]=mt(i,j); } int i=0; F(i,n){//從頭到尾看一下有沒有指定字母開頭的單詞 if(tr[i][0]==ch){ vis[i]++; an=tr[i].size(); dfs(i); vis[i]--; } } cout<<ans; return 0; }