記憶化搜尋,是最容易寫,也是效率較高的一種做法。
雖然本質上是dfs這種搜尋的思路,但其對搜尋過的狀態進行記錄,從而完成對未知狀態的推導,實際上也是一種dp的思想。
洛谷p1434 [shoi2002]滑雪(傳送門)
輸入輸出格式輸入格式:
輸入的第一行為表示區域的二維陣列的行數r和列數c(1≤r,c≤100)。下面是r行,每行有c個數,代表高度(兩個數字之間用1個空格間隔)。
輸出格式:
輸出區域中最長滑坡的長度。
輸入輸出樣例乍一看,這不是一道水題嗎?輸入樣例#1:
5 51 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
輸出樣例#1:
25
問:兔*除了水部落格,他還會幹什麼?
答:唱、跳、搞事情。
該題讓我們找一條最長的路
其實我們列舉出發點,從出發點向四周擴充套件即可解題
於是蒟蒻的兔子花了5分鐘,打出了**
#include
using
namespace std;
intread()
while
(ch>=
'0'&&ch<=
'9')
return x*f;
}//pqh式專屬快讀
int n,m;
int a[
1010][
1010];
int ans,ans2;
//全圖最長,列舉一點
void
cin()}
return;}
int dir[4]
[2]=
,,,}
;//行走方向
boolin(
int x,
int y)
intdfs
(int x,
int y)
} ans2=mx+1;
return ans2;
}int
main()
} cout<
return0;
}
但是,你會發現乙個神奇的事情
您tle了:)
只得了90分,挺滿意的
兔子才沒有這麼蒟蒻
剛剛的暴搜確實很暴力,但好在還是過了9組測試資料
仔細思考(足足花了兔子三秒鐘呢 ),於是決定寫動歸。
無腦推一波動態轉移方程,什麼,沒有??
狀態並不是固定的,於是,我們需要用到記憶化搜尋。
記憶化搜尋,其實就是用搜尋的方式,替換了動歸只會按照迴圈遍歷而對狀態轉移方位不確定的圖無法完成的缺點(好像這句話不通,不要在意這些細節 )
記憶化搜尋,結合動歸記錄之前狀態的優點。
記憶化搜尋可以排除一些無效狀態,但動歸總要遍歷所有的狀態。
記憶化搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上比動態規劃要低很多。
所以,記憶化搜尋才是王道。
上圖是搜尋思路,於是我們可以得到以下記憶化搜尋
int a[
1010][
1010];
int dp[
1010][
1010];
intdfs
(int x,
int y)
}return dp[x]
[y];
}
按這個思路打一遍,於是就ac了.
#include
using
namespace std;
intread()
while
(ch>=
'0'&&ch<=
'9')
return x*f;
}//pqh式專屬快讀
int n,m;
int a[
1010][
1010];
int dp[
1010][
1010];
int ans;
void
cin()}
return;}
int dir[4]
[2]=
,,,}
;boolin(
int x,
int y)
intdfs
(int x,
int y)
}return dp[x]
[y];
}int
main()
}
cout<
return0;
}
洛谷p1464 function(傳送門) 動態規劃 記憶化搜尋
記憶化搜尋顧名思義是在搜尋的過程中通過記錄搜尋的中間狀態從而達到減少重複搜尋的方法,通常用在搜尋樹 現重複子節點的情況。例題 滑雪 給定乙個r行c列的矩陣,表示乙個矩形網格滑雪場。矩陣中第 i 行第 j 列的點表示滑雪場的第 i 行第 j 列區域的高度。乙個人從滑雪場中的某個區域內出發,每次可以向上...
動態規劃之記憶化搜尋
一.動態規劃 動態規劃 dynamic programming 與 分治思想 有些相似,都是利用將問題分 為子問題,並通過合併子問題的解來獲得整個問題的解。於 分治 的不同之處在 於,對於乙個相同的子問題動態規劃演算法不會計算第二次,其實現原理是將每乙個計算過的子問題的值儲存在乙個表中。二.記憶化搜...
動態規劃 記憶化搜尋(滑雪)
給定乙個r行c列的矩陣,表示乙個矩形網格滑雪場。矩陣中第 i 行第 j 列的點表示滑雪場的第 i 行第 j 列區域的高度。乙個人從滑雪場中的某個區域內出發,每次可以向上下左右任意乙個方向滑動乙個單位距離。當然,乙個人能夠滑動到某相鄰區域的前提是該區域的高度低於自己目前所在區域的高度。下面給出乙個矩陣...