上乙個專題在這裡:dfs深度優先搜尋專題01
p1331 海戰
還是水窪問題,這題特殊的地方在於它只能是方形。
所以我們先對是否存在非方形進行判斷,如果非法,直接輸出並return掉
然後就都是合法的,轉成了水窪問題
#include
#include
#include
#include
#include
#include
#include
//#include
using
namespace std;
typedef
long
long ll;
int n,m;
char a[
1010][
1010];
int dx=
;int dy=
;bool
check
(int x,
int y)
//存在'l'形即為不合法
void
dfs(
int x,
int y)}}
intmain()
}for
(int i =
0; i < n; i++)}
}int ans =0;
for(
int i =
0; i < n; i++)}
} cout <<
"there are "
<< ans <<
" ships."
<< endl;
}
p1460 [usaco2.1]健康的荷斯坦奶牛 healthy holsteins
這題的題目我讀了好久??
#include
#include
#include
#include
#include
#include
#include
//#include
using
namespace std;
typedef
long
long ll;
int n,m;
int a[55]
;//每種飼料最小的維他命需求量
int b[25]
[55];
//b[i][j]表示第i包飼料的第j種維他命含量
int c[55]
;//在搜尋過程中儲存可行解(存的是選中的飼料的下標)
int ans[55]
;//儲存最小可行解(存的是飼料的下標)
int mmin=
0x3f3f3f3f
;bool
check
(int x)
//判斷選中的x種飼料是否滿足最小的維他命需求量
if(sum < a[i]
)return
false
;//第i種維他命的含量不夠
}return
true
;//前面所有都沒返回false
}void
dfs(
int now,
int num)
//now表示當前搜尋到了第now種飼料,num表示當前選了幾種飼料}}
return;}
c[num +1]
= now;
//選擇的第num種飼料的下標是now
dfs(now +
1, num +1)
;//要第num個飼料,開始搜尋第num+1個
c[num +1]
=0;//回溯
dfs(now +
1, num)
;//不要第num個飼料,開始搜尋第num+1個
}int
main()
cin >> m;
for(
int i =
1; i <= m; i++)}
dfs(1,
0); cout << mmin <<
" ";
for(
int i =
1; i <= mmin; i++
) cout << endl;
}
p1123 取數遊戲
#include
#include
#include
#include
#include
#include
#include
//#include
using
namespace std;
typedef
long
long ll;
int n,m;
int a[11]
[11];
int valid[11]
[11];
int mx =
-0x3f3f3f3f
;int sum;
int dx=
;int dy=
;void
dfs(
int x,
int y)
if(x == n +1)
//當x到邊界時,搜尋結束,更新最大值
dfs(x, y +1)
;//不取(x,y)
if(valid[x]
[y]==0)
//取(x,y)且(x,y)合法
dfs(x, y +1)
;for
(int i =
0; i <
8; i++
)//回溯
sum -
= a[x]
[y];}}
intmain()
}dfs(1
,1);
cout << mx << endl;
}}
p1019 單詞接龍
幾個要點
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ios ios::sync_with_stdio(false)
//#include
using
namespace std;
typedef
long
long ll;
int n;
string s[25]
;int used[25]
;int mx =-1
;int
check
(string s, string t)
//求s和t重疊部分的長度
if(flag)
return i;
}return0;
}void
dfs(string str,
int len)}}
intmain()
dfs(
' '+ s[n],1
);//因為check需要重疊部分小於最短長度-1,所以要從前面新增乙個無意義充長度的' '
cout << mx << endl;
}
p1101 單詞方陣
找到延伸的方向,按那個方向dfs,用結構體儲存路徑
來自洛谷題解的思路
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
struct node
c[110];
int n;
char a[
110]
[110
],stand=
"yizhong"
;int vis[
110]
[110];
int dx=
;int dy=
;int k;
void
dfs(
int x,
int y, node c,
int k,
int cur)
}else}}
intmain()
memset
(vis,0,
sizeof
(vis));
for(
int i =
0; i < n; i++)}
}}}for
(int i =
0; i < n; i++
)printf
("\n");
}}
深度優先搜尋DFS
作為搜尋演算法的一種,dfs對於尋找乙個解的 np 包括npc 問題作用很大。但是,搜尋演算法畢竟是 時間複雜度是o n 的階乘級演算法,它的效率比較低,在資料規模變大時,這種演算法就顯得力不從心了。關於深度優先搜尋的效率問題,有多種解決方法。最具有通用性的是剪枝 prunning 也就是去除沒有用...
深度優先搜尋 DFS
深度優先搜尋 縮寫dfs 有點類似廣度優先搜尋,也是對乙個連通圖進行遍歷的演算法。它的思想是從乙個頂點v 0開始,沿著一條路一直走到底,如果發現不能到達目標解,那就返回到上乙個節點,然後從另一條路開始走到底,這種盡量往深處走的概念即是深度優先的概念。你可以跳過第二節先看第三節,還是引用上篇文章的樣例...
深度優先搜尋(dfs)
深度優先搜尋的一般步驟 1 從頂點v出發,訪問v。2 找出剛才訪問過的頂點的第乙個未被訪問的鄰接點,訪問該頂點。以該頂點為新頂點,重複此步驟,直到剛訪問的頂點沒有沒有未被訪問過的鄰接點為止。3 返回前乙個訪問過的仍有未被訪問過的鄰接點的頂點,找出該頂點的下乙個未被訪問過的鄰接點,訪問該頂點。4 重複...