资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。
输入格式
第一行输入一个正整数n。
以下n行描述该方格。金币数保证是不超过1000的正整数。
输出格式
最多能拿金币数量。
样例输入
3
1 3 3
2 2 2
3 1 2
样例输出
11
数据规模和约定
n<=1000
这里可以归类为动态规划路径问题
从左上角到右下角只能向下移动或向右移动
那任意寻找一个坐标,除了最左边和最上边的情况的话他的都只能通过上方过来或是左边过来,但是要拿金币更多,就选择金币多的
这样也就能保证当前位置是从左上角过来的拿金币最佳情况
| 1 |3|3|
|–|–|–|–|
|2|2|2|
|3|1|2|
1 | 4 | 7 |
---|---|---|
3 | 6 | 9 |
6 | 7 | 11 |
所以
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + table[j][j]
边界情况
dp[0][i] = dp[0][i - 1] + table[0][I]
dp[i][0] = dp[i - 1][0] + table[I][0]
这里如果要转换成一唯数组
每个地方需要什么?
需要的是上一层结果和刚刚计算过的结果
上一层的结果有了就是本身
刚刚计算过的结果就是左边的部分
dp[i] = max(dp[i], dp[i - 1]) + table[i][j]
边界情况
第一层
dp[i] = dp[i - 1] + table[0][I]
下面的每层第一个
dp[0] = dp[0] + table[I][0]
二维数组
import java.util.*;
class Main {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int n = scanner.nextInt();
int table[][] = new int[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
table[i][j] = scanner.nextInt();
}
}
int dp[][] = new int[n][n];
dp[0][0] = table[0][0];
for(int i = 1; i < n; i++) {
dp[i][0] = table[i][0] + dp[i - 1][0];
dp[0][i] = table[0][i] + dp[0][i - 1];
}
for(int i = 1; i < n; i++) {
for(int j = 1; j < n; j++) {
dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]) + table[i][j];
}
}
System.out.print(dp[n - 1][n - 1]);
}
}
一维数组
import java.util.*;
class Main {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int n = scanner.nextInt();
int array[] = new int[n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i == 0) array[j] = (j - 1 >= 0 ? array[j - 1] : 0) + scanner.nextInt();
else if(j != 0) array[j] = Math.max(array[j], array[j - 1]) + scanner.nextInt();
else array[j] = array[0] + scanner.nextInt();
}
}
System.out.print(array[n - 1]);
}
}
二维数组没法通过全部案例