dfs剪枝的應用以及bfs

2021-10-03 07:54:16 字數 3603 閱讀 2545

奇怪的電梯

題目描述

呵呵,有一天我做了乙個夢,夢見了一種很奇怪的電梯。大樓的每一層樓都可以停電梯,而且第i

ii層樓(1≤

i≤n)

(1in)

(1≤i≤n

)。電梯只有四個按鈕:開,關,上,下。上下的層數等於當前樓層上的那個數字。當然,如果不能滿足要求,相應的按鈕就會失靈。例如:3,3

,1,2

,5

3,3,1,2,5

3,3,1,

2,5代表了ki(

k1=3

,k2=

3⋯

)k_i(k_1=3,k_2=3)

ki​(k1

​=3,

k2​=

3⋯),從1

11樓開始。在1

11樓,按「上」可以到4

44樓,按「下」是不起作用的,因為沒有−2-2

−2樓。那麼,從a

aa樓到b

bb樓至少要按幾次按鈕呢?

輸入格式

共二行。

第一行為33個用空格隔開的正整數,表示n,a

,b(1

≤n

≤200,1

≤a,b

≤n)n

,a,b

(1≤n

≤200,1

≤a,b

≤n

n,a,b(1≤n≤200, 1≤a,b≤n)n,a,b(1≤n≤200,1≤a,b≤n

n,a,b(

1≤n≤

200,

1≤a,

b≤n)

n,a,

b(1≤

n≤20

0,1≤

a,b≤

n)。第二行為n

nn個用空格隔開的非負整數,表示k

ik_i

ki​。

輸出格式

一行,即最少按鍵次數,若無法到達,則輸出−1-1

−1。深度優先搜尋

如果單純的暴力搜尋,會有很多重複的搜尋,比如某一次搜尋中已經來過了1

11樓,但是進過了一番波折又來到了1

11樓,那麼勢必會重複之前那個過程,所以之前來過的樓就不能再來一次了。

#include

#include

using

namespace std;

int floor[

205]

,n;bool map[

205]

;int min = int_max;

//獲取int的最大值

void

dfs(

int,

int,

int,

int)

;int

main()

if(begin == end)

dfs(begin,end,begin,0)

;if(min==int_max)

cout<<-1

;else cout<}void

dfs(

int begin,

int end,

int now,

int times)

return;}

if(now-floor[now]

>=0&&

!map[now])if

(now+floor[now]

<=n&&

!map[now]

)}

結果超時了兩個點,所以還需要進一步的剪枝,對於如何剪枝,原則是如果這個搜尋是沒有必要的就是把它剪掉,比如求幾個數相乘等於乙個數,如果發現在相乘的過程中已經大於這個數了,且乘的數都大於1

11,那麼就不要用搜下去了。

對於這道題因為我們是在尋找最小值,且每一次搜尋值都會增加,所以在搜的過程中如果發現值已經大於最小值了,就不要再搜了。

改進後的**

#include

#include

using

namespace std;

int floor[

205]

,n;bool map[

205]

;int min = int_max;

void

dfs(

int,

int,

int,

int)

;int

main()

if(begin == end)

map[begin]

=true

;dfs

(begin,end,begin,0)

;if(min==int_max)

cout<<-1

;else cout<}void

dfs(

int begin,

int end,

int now,

int times)

return;}

if(times>min)

return;if

(now-floor[now]

>=0&&

!map[now-floor[now]])

if(now+floor[now]

<=n&&

!map[now+floor[now]])

}

完美通過!!

廣度優先搜尋f

sbfs

bfs,於是我也來做一下順便複習一下

#include

#include

//使用stl

using

namespace std;

int floor[

205]

, n;

int map[

205]

;int flag, begin;

queue<

int> q;

//建立乙個佇列,int可以是任意的資料型別

intbfs

(int

,int);

intmain()

t =bfs(begin, end);if

(flag)

cout << t;

else

cout <<-1

;}intbfs

(int now_floor,

int end)

if(temp_floor - floor[temp_floor]

>0&&

!map[temp_floor - floor[temp_floor]]&&

temp_floor - floor[temp_floor]

!= begin)

if(temp_floor + floor[temp_floor]

<=n &&

!map[temp_floor + floor[temp_floor]]&&

temp_floor + floor[temp_floor]

!= begin)

}}

可以看到使用bfs就不用考慮剪枝這種細節,但是bfs編寫起來麻煩了一點

DFS 剪枝 BFS 鳴人和佐助

佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?已知一張地圖 以二維矩陣的形式表示 以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每乙個單位的查克拉可以打敗乙個大蛇丸的手下。假設鳴人可以往上下左右四個...

UVA 11882 dfs搜尋 bfs剪枝

uva 11882 dfs搜尋 bfs剪枝 給你乙個r c的數字矩陣,要求從任意乙個點開始走,只能上下左右走,求走的過數連線起來最大是多少。直接dfs每乙個數字,在每一層dfs中,加上bfs 判斷剩下的數連線起來能否大於當前的ans 不能的話 剪枝了。雖然思路是這樣的,但昨天一直tle,或許姿勢不對...

dfs和bfs的應用

dfs 能找到可行的路徑,所需時間長,需要標記位置 bfs 能找到最短的路徑,所需空間長,需要出入佇列 兩個搜尋的相同點是都利用了二維陣列的圖,有的時候都用了標記方法。但是dfs,我覺得沒什麼變化,就這樣了。但是bfs,1.可以用stl的queue,但是,沒辦法對付路徑記錄。2.可以用自己寫的結構體...