跳转至

摘花生

原题链接

Hello Kitty想摘点花生送给她喜欢的米老鼠。

她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。

地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就能摘走该它上面所有的花生。

Hello Kitty只能向东或向南走,不能向西或向北走。

问Hello Kitty最多能够摘到多少颗花生。

输入格式

第一行是一个整数T,代表一共有多少组数据。

接下来是T组数据。

每组数据的第一行是两个整数,分别代表花生苗的行数R和列数 C。

每组数据的接下来R行数据,从北向南依次描述每行花生苗的情况。每行数据有C个整数,按从西向东的顺序描述了该行每株花生苗上的花生数目M。

输出格式

对每组输入数据,输出一行,内容为Hello Kitty能摘到得最多的花生颗数。

数据范围

  • \(1≤T≤100\),
  • \(1≤R,C≤100\),
  • \(0≤M≤1000\)

输入样例:

1
2
3
4
5
6
7
2
2 2
1 1
3 4
2 3
2 3 4
1 6 5

输出样例:

1
2
8
16

思路

状态定义:

dp[i][j] 表示到达第 i 行、第 j 列时所有可能采摘到的花生数的集合

状态属性:

最大值

状态转移方程:

dp[i][j] 只可能从上方 dp[i - 1][j] 和左方 dp[i][j - 1] 的方块转移得出,即推出状态转移方程:

\[dp[i][j] = \max(dp[i - 1][j], dp[i][j - 1]) + w[i][j]\]

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>
using namespace std;

const int N = 110;

int n, m;
int dp[N][N];

void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> dp[i][j];

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            dp[i][j] += max(dp[i - 1][j], dp[i][j - 1]);

    cout << dp[n][m] << endl;
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        solve();
    }

    return 0;
}
回到页面顶部