題目大意:
乙個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,...