DFS中的奇偶剪枝學習筆記

2021-09-07 13:16:54 字數 3964 閱讀 5666

編輯

現假設起點為(sx,sy),終點為(ex,ey),給定t步恰好走到終點, s

|

|

|

+

e

如圖所示(「|」豎走,「—」橫走,「+」轉彎),易證abs(ex-sx)+abs(ey-sy)為此問題類中任意情況下,起點到終點的最短步數,記做step,此處step1=8; s

+

|

+

|

+

e

如圖,為一般情況下非

最短路徑的任意走法舉例,step2=14;

step2-step1=6,偏移路徑為6,偶數(易證);

編輯 推廣之,若 t-[abs(ex-sx)+abs(ey-sy)] 結果為非偶數(奇數),則無法在t步恰好到達;

返回,false;

反之亦反。

編輯 鑑於很多同學對奇偶剪枝根本原理的興趣,所以hj決定再補充一下本詞條。

還是以這個為例子吧,現在我把矩陣填滿 0 和 1

[1] 0

1

0

1 01

0

1

0 10

1 01

0101

010

1

0

1

0

我們現假設從 0 開始走,則不難證明,

從任意 0 走到任意 1 始終是奇數步;

從任意 0 走到任意 0 始終是偶數步;

引用描述裡的「例子」, s 到 e 的最短步數為 t (當然你也可以理解成此時到終點剛好剩餘 t 步等等)。

則,我們從 s 到 e 的步數之和(或者說總距離)總可以表示成 sum= t + extra ( extra>=0 ),其中 extra 表示額外的步數。

[2]比如「例子」裡面的,做例1吧 s

+

|

+

|

+

e

此時 t=8,sum=14,所以我們容易得到 extra=6。也就是說按照這個走法,需要在最短的步數上再走額外的 6 步(先不用太在意這些偏移是在什麼地方產生的)。

在來乙個例2吧, s

+

|

+

| +—

e+—

此時,t=7,sum=15,所以我們也容易得到 extra=8。

根據理科生的天性,由這兩個一般性的例子,我們很容易嗅察到 extra 都為偶數。先帶著疑惑,

再來看我給的 0 、1 矩陣。 0

1

0

1 01

0

1

0 10

1 01

0101

010

1

0

1

0

設左上角座標為(1,1),右下角座標為(5,5).

那麼我們給的例1,

起點 s 的座標為(1,1),此點為「0」;

終點 e 為(5,5),此點為「0」。

所以t=8,為偶數。

現在我們再倒過來看,從終點(也就是 e )出發,把最短步數 t=8 耗費掉,不妨這樣走, s

++—|

+——

e

如圖所示從 e (5,5)耗費 8 步走到了(1,5)點。

因為是從 0 走偶數步,所以走到的座標也一定是 0 ,就像這裡的(1,5)點是 0 一樣。

這是乙個遞迴的過程,首先如果從0開始,目的地也是0,那末其中的最短距離t必然是個偶數,可其中有可能有障礙物或需要繞彎的情況,那末我們就現將最短距離t用於繞彎,從開始的0,走t步不管怎麼走都只能到0,而這個0到終點0的最短路徑t也必然是偶數,一直遞迴下去,直到你繞夠了到達終點,這中間你額外的步數都是偶數。

注意到,(1,5)點和起點 s (1,1)都是 0,也就是說,這個 extra 必然是偶數!

再看例2,同樣從終點 e 開始耗費 t=7 步,

則所到的點一定是 0 (不管她在**),再從這個點回到起點 s ,所用的 extra 也必然是個偶數!

所以無論如何,sum= t + extra ( extra>=0 ) 中的 extra 都是乙個偶數

那麼我們就可以用公式 t-[abs(ex-sx)+abs(ey-sy)] 計算出extra是否為偶數來判斷當前點能否恰好在這麼多步到達終點了。

有的同學可能會說以 1 為 起點呢。。其實是一樣的啦,自己去搗鼓吧。

核心**:

ans=t-time-abs(dx-x)-abs(dy-y); 

if(ans<0||ans&1) return;

把矩陣看成如下形式:

0 1 0 1 0 1

1 0 1 0 1 0

0 1 0 1 0 1

1 0 1 0 1 0

0 1 0 1 0 1

從為 0 的格仔走一步,必然走向為 1 的格仔 。

從為 1 的格仔走一步,必然走向為 0 的格仔 。

即: 從 0 走向 1 必然是奇數步,從 0 走向 0 必然是偶數步。

所以當遇到從 0 走向 0 但是要求時間是奇數的或者 從 1 走向 0 但是要求時間是偶數的,都可以直接判斷不可達!

比如有一地圖:

s...

....

....

....

...d

要求從s點到達d點,此時,從s到d的最短距離為s = abs ( dx - sx ) + abs ( dy - sy )。

如果地圖**現了不能經過的障礙物:

s..x

xx.x

...x

.***

...d

此時的最短距離s' = s + 4,為了繞開障礙,不管偏移幾個點,偏移的距離都是最短距離s加上乙個偶數距離。

就如同上面說的矩陣,要求你從0走到0,無論你怎麼繞,永遠都是最短距離(偶數步)加上某個偶數步;要求你從1走到0,永遠只能是最短距離(奇數步)加上某個偶數步。

這裡我來講一下搜尋中要用到的奇偶剪枝的原理:

看張圖,沒障礙物#時,s到e的最短路長為6,但是當有障礙物時,就要繞行了

看這張圖,黑色為最短路徑,當他繞行(紅色加藍色部分)時,其中藍色部分其實還是最短路徑部分平移來的,所以多走的步數也就是紅色部分

對於紅色部分我們可以分為兩部分,一部分是遠離最短路徑的步數,另一部分是回到最短路徑的部分,他們一定是對稱的,所以多走的步數一定是偶數!!!

所以要是問走x步能否到達e,就算出最短路徑長y,如果x-y是偶數就能到達,否則不能到達!

DFS所用到的奇偶剪枝

把矩陣看成如下形式 0 1 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0 1 從為 0 的格仔走一步,必然走向為 1 的格仔 從為 1 的格仔走一步,必然走向為 0 的格仔 即 從 0 走向 1 必然是奇數步,從 0 走向 0 必然是偶數...

hdu 1010 dfs,奇偶剪枝

背景 熟悉dfs,第一次遇見了剪枝,各種剪枝。奇偶剪枝 開始一直超時,用了奇偶剪枝之後瞬間優化到312ms。對於乙個沒有障礙的圖,起點 s 到終點 的理想最短路徑是 而如果中間有障 礙物的話,路徑是在理想最短路徑上加上乙個偶數 可以證明 這樣可以看來,任何路徑和理想最短路徑是同奇偶的。這樣就可以剪去...

HDU1010 奇偶剪枝 DFS

第一次做剪枝的題目,剪枝,說實話研究的時間不短。好像沒什麼實質性的進展,遇到題目。絕對有會無從下手的感覺,剪枝越來越神奇了。hdu1010一道剪枝的經典題目,自己當初想用bfs過。提交了10幾遍wa,後來查了是剪枝最終死心了 ps 第一次寫剪枝題目,用了乙個模擬地圖來做奇偶性的判定條件進行剪枝,大牛...