174. 地下城游戏-7月12日

时间:2020-07-12 14:05:22   收藏:0   阅读:45

题目

174. 地下城游戏

技术图片

 

 

 

我的思路

根据题目中的条件,M*N的网格以及移动路线只能向右或者向下,很容易想到用动态规划迭代的方法,去依次计算每个网格的情况。

我一开始的想法是从左上角推往右下角,可是在推导中遇到了困难:

首先是发现可能需要两个辅助数组来存储相关数据,一个是最小初始健康点数,另一个是当前点数。而这两个条件的重要程度无法比较,从而无法进行推导。比如:从左边过来的路径要求初始最小健康点数比从上面过来的要求初始健康点数少,同时从上面过来的路径有更多的当前点数。这时两种选择会因为后续路径的不同而各有优劣。

在这个地方我的思路便被卡住了,个人理解以后在遇到动态规划的问题时,状态转移必须是确定的,如果多个条件的重要程度无法比较或者相同,那么可能得换思路(比如从前往后推导不行试试反方向推导)

从右下角往左上角推导,则不会遇到复杂的情况。只需要一个辅助二维数组,对应位置的存储内容是:当前位置要抵达重点至少需要的健康点数。推导方法是temp=min(PointsRuquest[i+1][j]-D[i][j],PointsRuquest[i][j+1]-D[i][j]),PointsRequest[i][j]=max(1,temp)。注意保证抵达当前位置的生命点数大于0即可。

我的实现

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        vector<vector<int>> pointsRequest(dungeon.size());
        for(int i=0;i<dungeon.size();i++){pointsRequest[i].resize(dungeon[i].size());}
        for(int i=dungeon.size()-1;i>=0;i--){

            for(int j=dungeon[0].size()-1;j>=0;j--){
                if(i==dungeon.size()-1&&j==dungeon[0].size()-1){
                    pointsRequest[i][j]=max(1-dungeon[i][j],1);
                }else
                if(i==dungeon.size()-1){
                    pointsRequest[i][j]=max(pointsRequest[i][j+1]-dungeon[i][j],1);
                }else
                if(j==dungeon[0].size()-1){
                    pointsRequest[i][j]=max(pointsRequest[i+1][j]-dungeon[i][j],1);
                }else{
                    int temp = min(pointsRequest[i+1][j]-dungeon[i][j],pointsRequest[i][j+1]-dungeon[i][j]);
                    pointsRequest[i][j]=max(temp,1);
                }
                printf("(%d,%d):%d\n",i,j,pointsRequest[i][j]);
            }
        }
        return pointsRequest[0][0];
    }
};

时间复杂度和空间复杂度都是二维数组的大小:mn

拓展学习

注意动态规划问题,如果状态转移时遇到两个无法比较重要程度的条件,可能需要换思路。

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!