hdu 1078 記憶化搜尋

2021-07-06 03:39:07 字數 1529 閱讀 9158

hdu 1078

題意:每次可以朝乙個方向走k格,必須走到乙個數值比當前值大的點,問最多數值加起來能有多少,走到不能再走。

一開始定義錯了,定義dp[i][j] 為以(i,j)為終點時所能得到的最大值。

dp[i+t*dx][j+t*dy] = max(dp[i+t*dx][j+t*dy],dp[i][j] + a[i+t*dx][j+t*dy]) (1<=t<=k)

這樣tle了很久,因為會重複更新很多東西,有的格仔還不能保證這時所得到的是這個格仔所能得到的最大的時候就去更新別的格仔了,此時這個工作就是完全沒有用的。

比如樣例中(0,0) -> (0,1) ->(1,1) 此時(1,1)不是所能達到的最大,用(1,1)去更新了(2,1) ,但是(0,0) -> (0,1) ->(0,2)->(1,2) -> (1,1) 此時這個(1,1)才是所能達到的最大。 這時拿去更新(2,1,)才能得到最大。

感覺這種跟路徑有關的問題多是用dfs搞的,跟dp有關的,還經常要用到記憶化搜尋,自己很不敏感,果然還是dp練得太少了。。

修改定義:dp[i][j] 為以(i,j)為起點時所能得到的最大值。

**轉移方程:**dp[i][j] = max(dp[i+t*dx][j+t*dy]) (1<=t<=k) + a[i][j]

分解子問題:

在求max裡的時候又可以將(i+t*dx,j+t*dy)當做起點來找dp[i+t*dx][j+t*dy]這樣就可以下去遞迴找了。

這樣能夠保證一旦每個格仔算出結果就是所能獲得的最大值,就能運用記憶化搜尋來搞了。如果這個dp[i][j] 有值,那他就是所能獲得的最大值,直接返回dp[i][j]。

錯誤定義的**:

int dp[m][m]; //以(i,j)為終點的所能拿到的最大值

void dfs(int x,int y)}}

}

正確定義後:

#include 

#include

#include

#include

#include

using

namespace

std;

#define m 109

int a[m][m],dp[m][m]; //以(i,j)為起點的最多能拿到幾個

int dx[4] = ;

int dy[4] = ;

int n,k;

int ans;

int dfs(int x,int y)//返回以(x,y)為起點時最多能有幾個}}

//記憶化搜尋

return dp[x][y] = a[x][y] + maxx; //用自身的數加上最大的能轉移來的更新dp[i][j]

}int main()

memset(dp,0,sizeof(dp));

printf("%d\n",dfs(0,0));

}return

0;}

hdu 1078(記憶化搜尋)

題意 老鼠每次最多走k步停下來,停下的這個位置只能比上乙個停留的位置大,並獲取其價值,每次只能水平或垂直走,問最大能得到的價值 解題思路 這道題可以用記憶化搜尋解決,dp i j 表示老鼠在位置 i,j 時可以達到的最優值。因為dp的狀態是乙個有向無環圖,剛開始想會不會走死迴圈,但是這道題有乙個條件...

HDU 1078 記憶化搜尋

題目鏈結 題意是老鼠一開始在 0,0 點,每個點都有乳酪數目,如果老鼠走到 的話就獲得所有乳酪,老鼠只能水平走和垂直走,問怎麼走才能獲得最 酪數。輸入n和k,n是地圖大小,k是老鼠能走多遠。很簡單的一道題,注意超時,記住用記憶化,貌似就因為要記憶化才被hdu歸類進dp的。下面是 include in...

hdu1078 記憶化搜尋

題目鏈結fatmouse and cheese 乙個網格上有很多cheese,老師偷cheese吃,每次四鄰域最多走k步,下一步的cheese數必須必當前位置多,求能吃到的最多cheese 記憶化搜尋 如圖,從第一行的數開始,每次可以往左下或右下走一格,直到走到最下行,把沿途經過的數全部加起來。如何...