編輯
現假設起點為(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...要求從s點到達d點,此時,從s到d的最短距離為s = abs ( dx - sx ) + abs ( dy - sy )。....
....
....
...d
如果地圖**現了不能經過的障礙物:
s..x此時的最短距離s' = s + 4,為了繞開障礙,不管偏移幾個點,偏移的距離都是最短距離s加上乙個偶數距離。xx.x
...x
.***
...d
就如同上面說的矩陣,要求你從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 第一次寫剪枝題目,用了乙個模擬地圖來做奇偶性的判定條件進行剪枝,大牛...