AcWing1015_摘花生
AcWing1015.摘花生
題目連結:AcWing1015.摘花生
1. 題目描述
Hello Kitty想摘點花生送給她喜歡的米老鼠。
她來到一片有網格狀道路的矩形花生地(如下圖),從西北角進去,東南角出來。
地裡每個道路的交叉點上都有種著一株花生苗,上面有若干顆花生,經過一株花生苗就能摘走該它上面所有的花生。
Hello Kitty只能向東或向南走,不能向西或向北走。
問Hello Kitty最多能夠摘到多少顆花生。
輸入格式
第一行是一個整數
T
T
T
接下來是
T
T
T組資料。
每組資料的第一行是兩個整數,分別代表花生苗的行數
R
R
R和列數
C
C
C。
每組資料的接下來
R
R
R行資料,從北向南依次描述每行花生苗的情況。每行資料有
C
C
C個整數,按從西向東的順序描述了該行每株花生苗上的花生數目
M
M
M。
輸出格式
對每組輸入資料,輸出一行,內容為Hello Kitty能摘到得最多的花生顆數。
資料範圍
1
≤
T
≤
100
,
1 \leq T \leq 100,
1≤T≤100,
1
≤
R
,
C
≤
100
,
1 \leq R,C \leq 100,
1≤R,C≤100,
0
≤
M
≤
1000
0 \leq M \leq 1000
輸入樣例:
2
2 2
1 1
3 4
2 3
2 3 4
1 6 5
輸出樣例:
8
16
2. 解題思路
本題和AcWing898. 數字三角形的分析思路是一樣的,只是在走法上有略微的不同,本題的走法是向右和向下走,即由
(
i
−
1
,
j
)
→
(
i
,
j
)
(i - 1, j) \rightarrow (i, j)
(i−1,j)→(i,j)和
f
(
i
,
j
−
1
)
→
f
(
i
,
j
)
f(i, j - 1) \rightarrow f(i, j)
f(i,j−1)→f(i,j)。
D
P
{
狀
態
表
示
f
(
i
,
j
)
{
集
合
:
所
有
從
(
1
,
1
)
走
到
(
i
,
j
)
走
法
的
集
合
屬
性
:
m
a
x
(
路
徑
上
權
值
的
最
大
值
)
狀
態
計
算
:
對
於
(
i
,
j
)
可
以
從
(
i
−
1
,
j
)
和
(
i
,
j
−
1
)
轉
移
過
來
,
即
(
1
,
1
)
→
(
i
−
1
,
j
)
→
(
i
,
j
)
,
前
一
步
部
分
正
好
表
示
的
是
f
(
i
−
1
,
j
)
,
同
理
(
i
,
j
−
1
)
這
個
點
可
以
表
示
為
f
(
i
,
j
−
1
)
。
兩
者
取
一
個
m
a
x
,
再
加
上
w
(
i
,
j
)
的
值
即
可
得
到
f
(
i
,
j
)
的
結
果
。
DP\begin{cases} 狀態表示 f(i,j) \begin{cases} 集合:所有從(1, 1)走到(i, j)走法的集合 \\ \\ 屬性:max (路徑上權值的最大值) \end{cases}\\ \\ 狀態計算: 對於(i, j)可以從(i - 1, j)和(i, j - 1)轉移過來,\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 即(1, 1) \rightarrow (i - 1, j) \rightarrow (i, j), 前一步部分正好表示的是f(i - 1, j), \\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 同理(i, j - 1)這個點可以表示為f(i, j - 1)。\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 兩者取一個max,再加上w(i, j)的值即可得到f(i, j)的結果。 \end{cases}
最後答案是 f ( n , m ) f(n, m) f(n,m)。
3. 程式碼實現
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m, T;
int w[N][N];
int f[N][N];
int main()
{
scanf("%d", &T);
while (T --)
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
cin >> w[i][j];
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
f[i][j] = max(f[i - 1][j], f[i][j - 1]) + w[i][j];
printf("%d\n", f[n][m]);
}
return 0;
}
4. 注意事項
本題的初始化和數字三角形的區別是:雖然有非法狀態,但非法狀態在轉移時不會影響到正常狀態的更新,所以不用初始化。