一年前開始接觸c語言 後來學了演算法 因為沒堅持下來就放棄了一段時間,現在想重新撿起來,就算不為了拿下什麼獎,也為了自己以後能說起來我也堅持過學一些東西。
先說說為什麼寫dfs吧,最近打了場比賽,dfs題很多,突然就想到搜尋演算法在比賽中很常用,學會用的話很多題都很好寫,所以今天又去學了一下。
下面先把題掛一下:
這是一道簡單的:
其實就是乙個簡單的迷宮,入口是s,出口是e,#為不能走的路,輸出的最短時間就是最短路,直接掛**。
#include
#include
#include
#include
int min =
9999999
;int c[4]
[2]=
,,,}
;//上下左右四個方向
int m,n,r,t,q,w;
//m,n為行,列 r,t為終點座標,q,w為起點座標
char s[
1000][
1000];
void
dfs(
int x,
int y,
int step)
for(i =
0; i <
4; i++)if
(s[xn]
[yn]==0
)//0為可以走
}return;}
intmain()
getchar()
;}for(i =
0; i < m; i++
)else
if(s[i]
[j]==
'.')
else
if(s[i]
[j]==
'#')
//不可走的置為1
else
if(s[i]
[j]==
'e')}}
dfs(q, w,0)
;//從起點開始搜尋
printf
("%d"
, min)
;//最短路徑
}
這裡我是把符號都置為0和1,將地圖改變了一下。
相信大家都看得懂,下面開始寫我對dfs的理解:
1.深度優先搜尋,顧名思義,深度,我的理解就是一條路走到底,當深到不能再深了,我再退回來換條路深,直到沒路可以換即走完了所有情況,所以也叫暴力搜尋。
3.因為是窮舉所有情況,所以有時時間複雜度較高,至於如何改變,就涉及到dfs的剪枝,這裡先了解一下這個詞,具體我會在下面解釋。
下面掛乙個我在我喜歡的博主那裡拿來的樹,觀察一下dfs究竟是怎麼以深度搜尋的:
然後這個搜尋的順序就是
a->b->e->b->f->c->f->b->c->b->a->c->a->d->g->d->a
你可能會問,為什麼我b->f->c已經到過了c,回溯到b後還要再去c呢,其實很容易想明白,如果c是終點,那最短路當然不是a->b->f->c,當然是a->c,那這是怎麼做到的呢,這一點我在上面**上也有掛出,回溯後置為零的操作,這樣的話避免了因此錯過更優解法。還有乙個問題,那我到達c之後,為什麼不走a呢,顯而易見,那不就成環了嗎,你現在還處於走過a的狀態,a值為1,所以不能走。這樣也避免了無限迴圈搜尋的結果。這裡提一句最優化剪枝,如果我已經得到了a->c這條長度為2的路,那在之後所有路徑只要大於二,也就是說如果我走了兩步還沒到終點,我就不走了,我就要回到第一步再找其他的路了,這樣就省下了很多無用的搜尋。
然後再掛乙個不一樣的dfs:
很容易理解就是用最少的炸彈數炸掉3x3方格中所有的』e』,每個炸彈可以炸上下左右以及中間五個格,炸彈放的位置是隨意的,所以我們可以把每乙個位置放不放炸彈的所有情況全部列出來,即有2的九次方為512種情況,用dfs的話可以很快算出,下面看**:
#include
intmin
(int a,
int b)
//三目運算子寫函式
const
int dir[4]
[2]=
,,,}
;//上下左右
int atack[5]
[5];
//記錄每個位置被炸彈波及次數
char mp[5]
[5];
//地圖
int ans =
1e9;
void
dfs(
int x,
int y,
int bomb)
++atack[x]
[y];
//投放炸彈的情況
for(
int i =
0; i <
4; i++)if
(y ==3)
dfs(x +1,
1, bomb +1)
;//換下一行,使用炸彈,炸彈數加1
else
dfs(x, y +
1, bomb +1)
;//換下一列
--atack[x]
[y];
//不投放炸彈的情況
for(
int i =
0; i <
4; i++)if
(y ==3)
dfs(x +1,
1, bomb)
;//不投放炸彈,炸彈數不變
else
dfs(x, y +
1, bomb);}
intmain()
比上一題稍難一點,仔細看dfs的使用情況也不難理解,也就是記錄下每乙個位置投炸彈與不投炸彈的所有情況,再進行比較選出最少炸彈數的情況輸出。
剪枝:剪枝就是通過一些判斷,剪掉一些不必要的子樹,因為這個分枝上都不是我們想要的結果,就沒必要再去搜尋它了。比如,在走迷宮時,如果發現當前的步數已經超過了最優步數,那從這個狀態開始的搜尋全都多餘了,就可以省去大量的搜尋。還有一些重複性剪枝之類的都與此類似,就不在這裡多說了。
以後再有有趣的題我還是會掛上來的,可以繼續關注。
深度優先搜尋DFS
作為搜尋演算法的一種,dfs對於尋找乙個解的 np 包括npc 問題作用很大。但是,搜尋演算法畢竟是 時間複雜度是o n 的階乘級演算法,它的效率比較低,在資料規模變大時,這種演算法就顯得力不從心了。關於深度優先搜尋的效率問題,有多種解決方法。最具有通用性的是剪枝 prunning 也就是去除沒有用...
深度優先搜尋 DFS
深度優先搜尋 縮寫dfs 有點類似廣度優先搜尋,也是對乙個連通圖進行遍歷的演算法。它的思想是從乙個頂點v 0開始,沿著一條路一直走到底,如果發現不能到達目標解,那就返回到上乙個節點,然後從另一條路開始走到底,這種盡量往深處走的概念即是深度優先的概念。你可以跳過第二節先看第三節,還是引用上篇文章的樣例...
深度優先搜尋(dfs)
深度優先搜尋的一般步驟 1 從頂點v出發,訪問v。2 找出剛才訪問過的頂點的第乙個未被訪問的鄰接點,訪問該頂點。以該頂點為新頂點,重複此步驟,直到剛訪問的頂點沒有沒有未被訪問過的鄰接點為止。3 返回前乙個訪問過的仍有未被訪問過的鄰接點的頂點,找出該頂點的下乙個未被訪問過的鄰接點,訪問該頂點。4 重複...