小灶第五次作業 dp

2021-07-11 09:24:52 字數 1471 閱讀 8004

題目大意:

乙個n*m的格仔,baker vai要從(1,1)到(n,m)再回到(1,1),每到乙個格仔可以收集格仔上的數字(每個格仔只能走一次,(1,1)這個格仔除外),問最終蒐集的數字之和最大為多少?

解題思路:

可以把題目轉化為求兩個物件同時從(1,1)出發到(n,m)途中不能相遇,狀態轉移的時候可以用dp[step][x][y],step代表當前步數,x,y分別代表兩者當前所在的行(所在列可以直接求出來)。顯然step = m+n-1 時候是走到了右下角,題目要求只能向下走或者向左走,於是就說明你不可能繞圈圈,換句話說你只能離目標越來越近,不可能是繞道遠的地方再回去,也就省了很多麻煩,橫縱座標之後和步數是有明確的關係的,同時,無論你之前怎麼選某乙個位置都可以得到,不用擔心錯過和比較大的。然後就是狀態方程:ans = max(兩個都向下,乙個向右乙個向下,乙個向下乙個向右,都向右)注意,記憶化搜尋,如果以前搜到這裡過,直接返回,每一層算最後的ans加上的是本層的兩個人數,如果兩個橫座標相同,那麼第二個就不要了。

#include

#include

#include

using

namespace std;

int a[

110][

110],dp[

220][

110][

110];

int n, m;

intdfs

(int step,

int r1,

int r2)

int ans = dp[step][r1][r2];

if(ans !=-1

)return ans;

if(r1 < n && r2 < n)

ans =

dfs(step+1

,r1+1

,r2+1

);if

(r1 < n && step-r2+1

< m)

ans =

max(ans,

dfs(step+1

,r1+1

,r2));

if(r2 < n && step-r1+1

< m)

ans =

max(ans,

dfs(step+1

,r1,r2+1

));if

(step-r1+1

< m&&step-r2+1

< m)

ans =

max(ans,

dfs(step+1

,r1,r2));

ans += a[r1][step-r1+1]+

((r1==r2)?

0:a[r2][step-r2+1

]); dp[step][r1][r2]

= ans;

return ans;

}int

main

()return0;

}

第五次作業

一 問題及 include using namespace std class time void add a minute void add an hour void add seconds int n void add minutes int n void add hours int n voi...

第五次作業

當我們在討論多型性的時候,通常會用過載函式進行舉例,而這次發現的問題主要在過載運算子上,因此我希望通過對過載運算子的測試來得出乙個結論。我們想知道為什麼前置運算子和後置運算子會有區別,因此設計了乙個實驗來證明它 得到最終結果如預期那樣。通過這次作業,我能感受到前置和後置運算子的區別,通過x 和y x...

第五次作業

insert into student sno,sname,s sdept,sage values 201215128 陳冬 男 is 18 建表時規定學號唯一,而在建表時已經加入了該學號,所以不能有兩個相同學號。3.70 insert into student sno,sname,s sdept,...