ACWing动态规划DP采花生

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

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

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

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

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

ACWing动态规划DP采花生_第1张图片

输入格式

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

接下来是T组数据。

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

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

输出格式

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

数据范围

1≤T≤1001≤T≤100,
1≤R,C≤1001≤R,C≤100,
0≤M≤10000≤M≤1000

输入样例:

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

输出样例:

8
16

一道非常基础的动态规划问题

本题的模型是数字三角形。

这里我们从集合的角度来分析一下(闫式DP分析法)

ACWing动态规划DP采花生_第2张图片

我们需要从(1 , 1)这个位置走到(n , m) ,找到最后采得花生最多的方法。

我们可以先这样想,假设我们要求得某一条路线走到dp(i . j)时所采得的花生数量,那么我们可以这样想(曲线救国) :计算走到dp(i  , j)前一步花生的数量 , 然后再加上最后一步所得到的花生的数量即可,因此dp[i][j] 可以由dp[i - 1][j](左侧走过来) dp[i][j - 1](右侧走过来),我们只需要找到两条路线中其中采得花生多的一条路径即可

因此dp(n , m)就是采得花生的最大值

代码就直接附在下面,有需要可以参考一下

#include 
#include 
#include 
using namespace std;
const int N = 510;
int g[N][N];
int dp[N][N];
int t;
int n , m;
int main()
{
    cin >> t;
    while(t --){
        cin >> n >> m;
        for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                cin >> g[i][j];
            }
        }
        for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                dp[i][j] = max(dp[i - 1][j] + g[i][j] , dp[i][j - 1] + g[i][j]);
            }
        }
        cout << dp[n][m] << endl;
    }
    return 0;
}

你可能感兴趣的:(刷题集,刷题学习,动态规划,算法,图论)