变量简洁正确完整思路
动态规划dpij,左上到右下既需要路径和大,还需要初始生命值小,不满足无后效性,右下到左上,只需关心从ij到n-1m-1  ij需要的最小生命值

精确定义
dpij  从ij到n-1m-1需要的最小初始生命值,dp00是第一个格子,dpn-1n-1是右下

转移
-2 -3  3
-5 -10 1
10 30 -5   dpij至少需要1,什么时候需要更多,
dpi+1 j  dpi j+1     二者需要的最小初始生命值较小者minNeed, 如果[i][j]是负数,则
minNeed+abs[i][j]大于1,   如果是正数,只需要max(1,minNeed-[i][j])

初始化,一维动态规划
,dpn-1 j至少1,如果[n-1][j]负数,需要abs[n-1][j]+dpn-1 j+1
否则需要dpn-1 j+1
class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        int n=dungeon.size(),m=dungeon[0].size();
        vector<vector<int>>dp(n,vector<int>(m,0));
        if(dungeon[n-1][m-1]<0)dp[n-1][m-1]=1-dungeon[n-1][m-1];
        else dp[n-1][m-1]=1;
        for(int i=n-2;i>=0;i--){
            //cout<<i<<dp[i+1][m-1]<<endl;
            if(dungeon[i][m-1]<0)dp[i][m-1]=dp[i+1][m-1]-dungeon[i][m-1];
            else dp[i][m-1]=max(1,dp[i+1][m-1]-dungeon[i][m-1]);
        }
        for(int j=m-2;j>=0;j--){
            if(dungeon[n-1][j]<0)dp[n-1][j]=dp[n-1][j+1]-dungeon[n-1][j];
            else dp[n-1][j]=max(1,dp[n-1][j+1]-dungeon[n-1][j]);
        }
        for(int i=n-2;i>=0;i--){
            for(int j=m-2;j>=0;j--){
                int minNeed=min(dp[i+1][j],dp[i][j+1]);
                //cout<<i<<j<<' '<<minNeed<<endl;
                if(dungeon[i][j]<0)dp[i][j]=minNeed-dungeon[i][j];
                else dp[i][j]=max(1,minNeed-dungeon[i][j]);
            }
        }
        return dp[0][0];
    }
};

踩过的坑
遇bug别害怕,立刻想方法cout,检查大局
[i][j]正负分情况,为负,则dpij需要在原来较小的基础上+abs[i][j]
为正,则需要在原来较小的基础上-[i][j]因为有所补充,但是不能比1小
显然初始化是类似的一维动态规划

 

posted on 2021-08-06 16:04  offer快到碗里来~  阅读(48)  评论(0)    收藏  举报