蓝桥杯--算法训练--拿金币 java 思路+代码

问题描述

  有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。

输入格式

  第一行输入一个正整数n。
  以下n行描述该方格。金币数保证是不超过1000的正整数。

输出格式

  最多能拿金币数量。

样例输入

3
1 3 3
2 2 2
3 1 2

样例输出

11

数据规模和约定

  n<=1000

这是一道DP的入门题,如果知道DP(动态规划)算法的话,建议学习后再做会简单得多。

思路:

用一个二维数组map来存储带权图 ,map[i][j]表示i,j位置存放的金币

另建一个等大小的二维数组dp[i][j] 来存储当前位置取得的最大收益,dp[i][j]表示到达i,j位置后能取得的最大金币数

对于i,j>0的任意位置,总有dp[i][j] = max( dp[i][j-1] , dp[i-1][j] ) + map[i][j] 成立。

即:如果求dp[i][j]位置的最大金币数,只需要知道此位置上面的最大金币数与左边的最大金币数,取二者中的最大值 。

第一次我超内存了,原因是设置了一个max与每次求出的dp[i][j]比大小求最大值,当数据过大时会引起内存超限

解决办法就是不用设max值,dp[n-1][n-1]的值一定是最大值,换句话说,只要还能走,就还能再继续增加金币数,那么当不能走时,就是最大值了。

代码如下:

package DP;
import java.util.* ;
public class 拿金币 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in) ;
        int n = sc.nextInt() ;
        int[][] map = new int[n][n] ;
        for( int i = 0 ; i < n ; i++ ){
            for( int j = 0 ; j < n ; j++ ){
                map[i][j] = sc.nextInt() ;
            }
        }
        int[][] dp = new int[n][n] ;
        dp[0][0] = map[0][0] ;
        for( int i = 1 ; i < n ; i++ ){
            dp[i][0] = dp[i-1][0] + map[i][0];
            dp[0][i] = dp[0][i-1] + map[0][i] ;
        }
        for( int i = 1 ; i < n ; i++ ){
            for( int j = 1 ; j < n ; j++ ){
                dp[i][j] = Math.max(dp[i-1][j] ,dp[i][j-1]) + map[i][j] ;
            }
        }

        System.out.println(dp[n-1][n-1]);
    }
}

测评结果

评测点序号评测结果得分CPU使用内存使用下载评测数据
1正确10.00109ms22.39MB输入 输出
2正确10.00218ms34.91MB输入 输出
3正确10.00468ms91.96MB输入 输出
4正确10.00390ms94.16MB输入 输出
5正确10.00500ms94.50MB输入 输出
6正确10.00562ms161.6MB输入 输出
7正确10.00703ms169.6MB输入 输出
8正确10.00765ms169.0MB输入 输出
9正确10.00781ms173.2MB输入 输出
10正确10.00796ms176.1MB输入 输出
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值