zoukankan      html  css  js  c++  java
  • 174. Dungeon Game

    一、题目

      1、审题

      

      2、分析

        只能向右、向下移动的王子,从左上角要到右下角救公主,每经过一个方格,可能获得血瓶加血量,或者碰到怪物减血量,当王子血量 < 1 时就挂了,为了能成功救得公主,求王子的最小的初始血量。

    二、解答

      1、思路:

        方法一、

          采用二维数组 dp[][] 的动态规划方法:

          ①、使用数组  hp[i][j] 存储王子在位置 i,j 时所需的最小血量;从右下角向左上角进行计算;

          ②、hp 大小比方格多一行、多一列用于方便进行计算;且 hp 最后一行、最后一列初始化为 Integer.max;

          ③、 NEED = Min(hp[i+1][j], hp[i][j+1]) - dungeon[i][j]; // 即 从下方或从右方到达 (i, j) 时的最小血量需要,

             若 NEED <= 0, 则 hp[i][j] = 1,即可,否则, hp[i][j] = NEED;

        public int calculateMinimumHP2(int[][] dungeon) {
            
            int M = dungeon.length;
            int N = dungeon[0].length;
            
            int[][] hp = new int[M + 1][N+1];
            for (int i = 0; i < M; i++) {
                hp[i][N] = Integer.MAX_VALUE;
            }
            for (int i = 0; i < N; i++) {
                hp[M][i] = Integer.MAX_VALUE;
            }
            hp[M][N-1] = 1;
            hp[M-1][N] = 1;
            
            for (int i = M - 1; i >= 0; i--) {
                for (int j = N - 1; j >= 0; j--) {
                    int need = Math.min(hp[i + 1][j], hp[i][j + 1]) - dungeon[i][j];
                    hp[i][j] = need <= 0 ? 1: need;
                }
            }
            
            return hp[0][0];
        }

      方法二、

       采用一维数组 dp[] 的动态规划方法:

       也是从底部向上边进行计算,碰到边界情况要特殊处理。

        public int calculateMinimumHP(int[][] dungeon) {
            
            int M = dungeon.length;
            int N = dungeon[0].length;
            int[] dp = new int[N + 1];
            dp[N] = 1;
            int health = 0;
            for (int i = M - 1; i >= 0; i--) {
                for (int j = N - 1; j >= 0; j--) {
                    if(i == M - 1) // 处理最后一行 
                        health = dp[j + 1] - dungeon[i][j];
                    else if(j == N - 1) // 处理每一行的最后一列
                        health = dp[j] - dungeon[i][j];
                    else    // 有下边、右边的元素
                        health = Math.min(dp[j + 1], dp[j]) - dungeon[i][j];
                    
                    dp[j] = health <= 0 ? 1 : health;
                }
            }
            return dp[0];
        }
  • 相关阅读:
    如何在SQLite中创建自增字段?
    Windows XP平台下编译boost[1.47及以上]
    智能指针的向下转型
    采用Boost::filesystem操作文件
    CodeSmith访问数据库
    std::string的一些操作
    PDF加入内嵌字体
    悟空和唐僧的对话
    收获和教训的一天配置ds1401
    vxworks的一个changlog
  • 原文地址:https://www.cnblogs.com/skillking/p/9801288.html
Copyright © 2011-2022 走看看