算法训练 蓝桥杯 拿金币
问题描述
有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。
输入格式
第一行输入一个正整数n。
以下n行描述该方格。金币数保证是不超过1000的正整数。
输出格式
最多能拿金币数量。
样例输入
3
1 3 3
2 2 2
3 1 2
样例输出
11
思路
采用动态规划的思想,每次的最大数量应该是其上侧或左侧中的一个,选择最大的与自身相加,得到的数量就是最优解
代码
package 拿金币;
import java.util.Scanner;
/**
* 有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。
* 你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。
* 请问如何走才能拿到最多的金币。
*/
public class WithGold {
/**
* 采用动态规划的方式求解
* @param args
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//定义N
int len = sc.nextInt();
//定义N*N的方格
int [][]dp = new int[len][len];
for(int i = 0 ; i < len ; i++){
for(int j = 0 ; j < len ; j++){
//输入方格中的参数
dp[i][j] = sc.nextInt();
}
}
for(int i = 0 ; i < len ; i++){
for(int j = 0 ; j < len ; j++){
if (i == 0 && j == 0){
//如果是第一个格子,最大数量就是其本身
}else if (i == 0 && j > 0){
//第一行的格子的最大数量就是本身加上其左侧的格子的数量
dp[i][j] += dp[i][j-1];
}else if (j == 0 && i > 0){
//第一列的格子最大数量就是其本身加上其上侧格子的数量
dp[i][j] += dp[i-1][j];
}else {
//不是第一行或第一列的格子要比较其左侧和上侧的格子
//选择数量最大的一个格子与当前格子的数量相加
//求得的数量就是当前格子最大的数量
if (dp[i-1][j] > dp[i][j-1]){
dp[i][j] += dp[i-1][j];
}else {
dp[i][j] += dp[i][j-1];
}
}
}
}
System.out.println(dp[len-1][len-1]);
}
}