摘花生
【题目描述】
Hello Kitty想摘点花生送给她喜欢的米老鼠。她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就能摘走该它上面所有的花生。Hello Kitty只能向东或向南走,不能向西或向北走。问Hello Kitty最多能够摘到多少颗花生。
【输入】
第一行是一个整数T,代表一共有多少组数据。1≤T≤100
接下来是T组数据。
每组数据的第一行是两个整数,分别代表花生苗的行数R和列数 C(1≤R,C≤100)
每组数据的接下来R行数据,从北向南依次描述每行花生苗的情况。每行数据有C
个整数,按从西向东的顺序描述了该行每株花生苗上的花生数目M(0≤M≤1000)
。
【输出】
对每组输入数据,输出一行,内容为Hello Kitty能摘到得最多的花生颗数。
【输入样例】
2
2 2
1 1
3 4
2 3
2 3 4
1 6 5
【输出样例】
8
16
思路:此题其实和数字三角形那个题原理是一样的,同样的我们也用动态规划来做。我们应该考虑状态分析和状态转移两部分,首先对于状态分析,根据数据范围我们可以得知可以用二维数组dp,对于dp[i][j]的含义为我们走到第i行第j列时所得的最大的花生数,我们从头开始走,一直走到最东南角即可,对于状态转移,我们可以知道对于每一个dp[i][j]是由正上和左边转移而来,即dp[i][j] = max(dp[i - 1][j] + a[i][j], dp[i][j - 1]),由此我们就可以敲代码了!
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int>PII;
const int N=3e5+10;
const int MOD = 1e9 + 7;
const int INF=0X3F3F3F3F;
const int dx[]={-1,1,0,0,-1,-1,+1,+1};
const int dy[]={0,0,-1,1,-1,+1,-1,+1};
const int M = 1e7 + 10;
int t;
int dp[1001][1010];
int a[1010][1010];
void solve()
{
int n, m;
cin >> n >> m;
memset(dp, 0, sizeof dp);
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
dp[i][j] = max(dp[i -1][j] + a[i][j], dp[i][j - 1] + a[i][j]);
}
}
cout << dp[n][m] << endl;
}
int main()
{
cin >> t;
while(t --){
solve();
}
return 0;
}