POJ 1088 滑雪記憶化搜尋簡單介紹

2021-09-22 02:17:52 字數 3579 閱讀 7613

michael喜歡滑雪百這並不奇怪, 因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待公升降機來載你。michael想知道載乙個區域中最長底滑坡。區域由乙個二維陣列給出。陣列的每個數字代表點的高度。下面是乙個例子

1 2 3 4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

乙個人可以從某個點滑向上下左右相鄰四個點之一,當且僅當高度減小。在上面的例子中,一條可滑行的滑坡為24−17

−16−1

24-17-16-1

24−17−

16−1

。當然25−24

−23−.

..−3

−2−1

25-24-23-...-3-2-1

25−24−

23−.

..−3

−2−1

更長。事實上,這是最長的一條。

輸入的第一行表示區域的行數r和列數c(1

<=r

,c<

=100

)c(1 <= r,c <= 100)

c(1<=r

,c<=1

00)。下面是r

rr行,每行有c

cc個整數,代表高度h,0

<=h

<

=10000

h,0<=h<=10000

h,0<=h

<=1

0000

輸出最長區域的長度。

5 5

1 2 3 4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

25
對於這道題思想很簡單就是把每個點都當做起始點依次進行遍歷(也就是乙個乙個進行搜尋找出最長的邊)但是很容易超時哦,因此我們可以把每個所有搜尋過得點進行一下記錄,這就運用到了記憶化搜尋(在這裡把它用的遞迴中這樣就減少了大量的執行時間);如果不了解,下面進行了一些介紹,哈哈!!!

搜尋的低效在於沒有能夠很好地處理重疊子問題;動態規劃雖然比較好地處理了重疊子問題,但是在有些拓撲關係比較複雜的題目面前,又顯得無奈。記憶化搜尋正是在這樣的情況下產生的,它採用搜尋的形式和動態規劃中遞推的思想將這兩種方法有機地綜合在一起,揚長避短,簡單實用,在資訊學中有著重要的作用。用乙個公式簡單地說*:記憶化搜尋=搜尋的形式+動態規劃的思想。

動態規劃:

就是乙個最優化問題,先將問題分解為子問題,並且對於這些分解的子問題自身就是最優的才能在這個基礎上得出我們要解決的問題的最優方案,要不然的話就能找到乙個更優的解來替代這個解,得出新的最優自問題,這當然是和前提是矛盾的。動態規劃不同於 貪心演算法,因為貪心演算法是從區域性最優來解決問題,而動態規劃是全域性最優的。用動態規劃的時候不可能在子問題還沒有得到最優解的情況下就做出決策,而是必須等待子問題得到了最優解之後才對當下的情況做出決策,所以往往動態規劃都可以用 乙個或多個遞迴式來描述。而貪心演算法卻是先做出乙個決策,然後在去解決子問題。這就是貪心和動態規劃的不同。

一般遇到乙個動態規劃型別的問題,都先要確定最優子結構,還有重疊子問題,這兩個是動態規劃最大的特徵,然後就是要寫 動態規劃的狀態方程,這個步驟十分十分的重要的,寫動歸方程是需要一定的經驗的,這可以通過訓練來達到目的。接著就是要自底向上的求解問題的,先將最小規模的子問題的最優解求出,一般都用一張表來記錄下求得的解,到後來遇到同樣的子問題的時候就可以直接查表得到答案,最後就是通過一步一步的迭代得出最後問題的答案了

我的理解最重要的東西就是一定會要乙個陣列或者其他的儲存結構儲存得到的子問題的解。這樣就可以省很多時間,也就是典型的空間換時間。

動態規劃的一種變形就是記憶化搜尋,就是根據動歸方程寫出遞迴式,然後在函式的開頭直接返回以前計算過的結果,當然這樣做也需要乙個儲存結構記下前面計算過的結果,所以又稱為記憶化搜尋。 記憶化搜尋遞迴式動態規劃

記憶化搜尋的思想記憶化搜尋的思想是,在搜尋過程中,會有很多重複計算,如果我們能記錄一些狀態的答案,就可以減少重複搜尋量

記憶化搜尋的適用範圍

根據記憶化搜尋的思想,它是解決重複計算,而不是重複生成,也就是說,這些搜尋必須是在搜尋擴充套件路徑的過程中分步計算的題目,也就是「搜尋答案與路徑相關」的題目,而不能是搜尋乙個路徑之後才能進行計算的題目,必須要分步計算,並且搜尋過程中,乙個搜尋結果必須可以建立在同型別問題的結果上,也就是類似於動態規劃解決的那種

也就是說,他的問題表達,不是單純生成乙個走步方案,而是生成乙個走步方案的代價等,而且每走一步,在搜尋樹/圖中生成乙個新狀態,都可以精確計算出到此為止的費用,也就是,可以分步計算,這樣才可以套用已經得到的答案

記憶化搜尋的核心實現

a) . 首先,要通過乙個表記錄已經儲存下的搜尋結果,一般用雜湊表實現

b).狀態表示,由於是要用雜湊表實現,所以狀態最好可以用數字表示,常用的方法是把乙個狀態連寫成乙個p進製數字,然後把這個數字對應的十進位制數字作為狀態

c).在每一狀態搜尋的開始,高效的使用雜湊表搜尋這個狀態是否出現過,如果已經做過,直接呼叫答案,回溯

d).如果沒有,則按正常方法搜尋

記憶化搜尋是類似於動態規劃的,不同的是,它是倒做的「遞迴式動態規劃」。

**如下:

(其實很簡單的哦)

#include

#include

#include

using

namespace std;

int dis[4]

[2]=

;int r,c;

int a[

101]

[101

],b[

101]

[101];

intdfs

(int x,

int y)

return b[x]

[y];

}int

main()

printf

("%d\n"

,sum);}

return0;

}

類似題目還有:【poj1579】function run fun,【hdu1501】zippe,【uva10118】free candies,

[hdu1428] 漫步校園,[nkoj3699] 送披薩~~等等有興趣可以去了解一下;

POJ 1088 滑雪 記憶化搜尋

滑雪 time limit 1000ms memory limit 65536k total submissions 79619 accepted 29637 description michael喜歡滑雪百這並不奇怪,因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你...

POJ 1088 滑雪 記憶化搜尋

description michael喜歡滑雪百這並不奇怪,因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待公升降機來載你。michael想知道載乙個區域中最長底滑坡。區域由乙個二維陣列給出。陣列的每個數字代表點的高度。下面是乙個例子 1 2 ...

POJ 1088 滑雪 記憶化搜尋

滑雪 time limit 1000ms memory limit 65536k total submissions 84463 accepted 31618 description michael喜歡滑雪百這並不奇怪,因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你...