*不求点赞,只求耐心看完,指出您的疑惑和写的不好的地方,谢谢您。本人会及时更正感谢。希望看完后能帮助您理解算法的本质*
一、题目描述:
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
二、暴搜:
思路:
本题和 [最低通行费] 两题解法一模一样,这里只给出代码,具体分析请跳转到 【最低通行费 – 详细分析,错过了就是一辈子】
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e2 + 10;
int g[N][N];
int n, m;
int ans;
void dfs (int x, int y, int sum)
{
if (x == n && y == m)
{
ans = max(sum + g[x][y], ans);
return ;
}
if (x+1 <= n){
dfs (x + 1, y, sum + g[x][y]);
}
if (y + 1 <= m){
dfs (x, y+1, sum + g[x][y]);
}
return ;
}
int main()
{
int t;
cin >> t;
while ( t -- )
{
cin >> n >> m;
memset (g, 0, sizeof (g));
ans = 0;
for (int i=1; i <= n; i ++)
for (int j=1; j <= m; j ++)
cin >> g[i][j];
dfs (1, 1, 0);
cout << ans << endl;
}
return 0;
}
记忆化搜索:
思路:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e2 + 10;
int g[N][N];
int memo[N][N];
int n, m;
int dfs (int x, int y)
{
if (memo[x][y] != -1)
return memo[x][y];
if (x == n && y == m){
return memo[x][y] = g[x][y];
}
if (x+1 <= n){
memo[x][y] = max(memo[x][y], dfs (x+1, y) + g[x][y]);
}
if (y+1 <= m){
memo[x][y] = max(memo[x][y], dfs(x, y+1) + g[x][y]);
}
return memo[x][y];
}
int main()
{
int t;
cin >> t;
while ( t -- )
{
memset (memo, -1, sizeof (memo));
cin >> n >> m;
for (int i=1; i<=n; i ++)
for (int j=1; j <= m; j ++)
cin >> g[i][j];
cout << dfs (1, 1) << endl;
}
return 0;
}
DP:
思路:
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e2 + 10;
int f[N][N];
int g[N][N];
int n, m;
int main()
{
int t;
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];
}
}
memset(f, 0, sizeof f);
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]) + g[i][j];
}
}
cout << f[n][m] << endl;
}
return 0;
}