题目描述
有一个 N x N 的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。
输入输出格式
输入格式
第一行有一个整数 N。
之后 N 行有 N 个整数,表示数组数组的所有元素,每个整数用一个空格隔开。
输出格式
一个整数。
输入输出样例1
输入
1
3
输出
3
输入输出样例2
输入
3
1 3 3
2 2 2
3 1 2
输出
11
说明提示
1≤n≤1000
思路
由于要使用动态规划来解决。
首先,我们要创建两个二维数组,一个是存地图的,一个是存sum
的res
数组。
res
数组在最开始要将第0
行和第0
列设为0
,表示在尚未计算时,sum
的初始值为0
。
然后,在设置一个函数int f(int i, int j)
用于更新res
数组的res[i][j]
。
f
函数的代码如下:
void f(int i, int j) {
res[i][j] = res[i][j-1]+a[i][j] > res[i-1][j]+a[i][j]? res[i][j-1]+a[i][j]: res[i-1][j]+a[i][j];
maxN = maxN < res[i][j]? res[i][j]: maxN;
}
f
函数表示的意思是res[i][j]
为res[i][j-1]+a[i][j]
和res[i-1][j]+a[i][j]
二者之一的最大值。
接着,就是说一下程序中函数res
数组的更新顺序,是从左到右逐层运行。
最终成果如下:
Code
#include <bits/stdc++.h>
using namespace std;
int res[1001][1001] = {0}, a[1001][1001] = {0}, maxN = 0;
void f(int i, int j) {
res[i][j] = res[i][j-1]+a[i][j] > res[i-1][j]+a[i][j]? res[i][j-1]+a[i][j]: res[i-1][j]+a[i][j];
maxN = maxN < res[i][j]? res[i][j]: maxN;
}
int main() {
int n;
cin >> n;
for(int i = 0; i <= n; ++i) {res[i][0] = res[0][i] = 0;}
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
cin >> a[i][j];
}
}
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
f(i, j);
}
}
cout << maxN;
}