【问题描述】
有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在左上角的格子里,每次可以从一个格子走到它右边或下边的格子里,请问如何走才能拿到更多的金币。
【输入格式】
第一行输入一个正整数n。
一下n行描述该方格。金币数是保证不超过1000的正整数。
【输出格式】
最多能拿金币数量。
【样例输入】
3
1 3 3
2 2 2
3 1 2
【样例输出】
11
【数据规模和约定】
n<=1000
【思路分析】
该题需使用动态规划(DP),先建立两个数组
num[]][]:表示每个方格的金币数。
dp[][]:表示走到该方格能拿到的最大金币数。
First:初始化dp[][]数组的最上面一行和最左边一行。(具体看代码,代码有注释。)
Second:动态规划dp[][]数组剩下的n-1方阵。
#include<stdio.h>
int main() {
int n;
scanf("%d", &n);
static int num[1000][1000], dp[1000][1000];//这里需用到静态建立数组,要不然栈中的内存不支持1000的二维数组规模。栈中最大好像只能接收到300多的规模。
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &num[i][j]);
}
}
dp[0][0] = num[0][0];//先初始化你的起点
i = 1;
j = 0;
while (i < n) {
dp[i][j] = dp[i - 1][j] + num[i][j];
i++;
}//初始化dp[][]数组最左边一行,这些只是固定的,只能有一种走法
i = 0;
j = 1;
while (j < n) {
dp[i][j] = dp[i][j - 1] + num[i][j];
j++;
}//初始化dp[][]数组最上边一行,这些也是固定的,只能有一种走法
for (i = 1; i < n; i++) {
for (j = 1; j < n; j++) {
int x = (dp[i][j-1]>=dp[i-1][j]?dp[i][j-1]:dp[i-1][j]);//该方格只能由上边和左边的方格走到,判断走到那个方格所拥有金币数量最多,就选择哪一个方格作为其上一步的方格
dp[i][j] = num[i][j] + x;//这里就是走到该位置所拥有的最多金币数
}
}
printf("%d",dp[n-1][n-1]);
return 0;
}