代码分析

典型的动态规划,走的顺序就是从下到上从右到左,举出几个例子,就可以确定状态转移方程

代码实现

int[][] dp=new int[dungeon.length][dungeon[0].length];
        //init
        //dp[dungeon.length-1][dungeon[0].length-1]=dungeon[dungeon.length-1][dungeon[0].length-1]>=0?1:dungeon[dungeon.length-1][dungeon[0].length-1]*-1+1;
        for(int i=dungeon.length-1;i>-1;i--)
        {
            for(int j=dungeon[0].length-1;j>-1;j--)
            {
                if(i==dungeon.length-1&&j==dungeon[0].length-1)//如果是最后一个元素
                {
                    dp[i][j]=dungeon[i][j]>=0?1:dungeon[i][j]*-1+1;
                }else if(i==dungeon.length-1)//如果是最后一行
                {
                    if(dp[i][j+1]==1&&dungeon[i][j]>0)
                    {
                        dp[i][j]=1;
                    }else if(dp[i][j+1]!=1&&dungeon[i][j]>=dp[i][j+1])
                    {
                        dp[i][j]=1;
                    }else
                    {
                        dp[i][j]=dp[i][j+1]-dungeon[i][j];
                    }
                }else if(j==dungeon[0].length-1)
                {
                    if(dp[i+1][j]==1&&dungeon[i][j]>0)
                    {
                        dp[i][j]=1;
                    }else if(dp[i+1][j]!=1&&dungeon[i][j]>=dp[i+1][j])
                    {
                        dp[i][j]=1;
                    }else
                    {
                        dp[i][j]=dp[i+1][j]-dungeon[i][j];
                    }
                }else
                {
                    int min=Math.min(dp[i+1][j],dp[i][j+1]);
                    //System.out.println(min);
                    if(min==1&&dungeon[i][j]>0)
                    {
                        dp[i][j]=1;
                    }else if(min!=1&&dungeon[i][j]>=min)
                    {
                        dp[i][j]=1;
                    }else
                    {
                        dp[i][j]=min-dungeon[i][j];
                    }
                }
            }
        }
        return dp[0][0];

优化的解法

 public static int calculateMinimumHP(int[][] dungeon) {
        int[][] dp=new int[dungeon.length][dungeon[0].length];
        for(int i=dungeon.length-1;i>-1;i--)
        {
            for(int j=dungeon[0].length-1;j>-1;j--)
            {
                if(i==dungeon.length-1&&j==dungeon[0].length-1)//如果是最后一个元素
                {
                    dp[i][j]=dungeon[i][j]>=0?1:dungeon[i][j]*-1+1;
                }else if(i==dungeon.length-1)//如果是最后一行
                {
                    dp[i][j]=Math.max(1,dp[i][j+1]-dungeon[i][j]);
                }else if(j==dungeon[0].length-1)
                {
                    dp[i][j]=Math.max(1,dp[i+1][j]-dungeon[i][j]);
                }else
                {
                    int min=Math.min(dp[i+1][j],dp[i][j+1]);
                    dp[i][j]=Math.max(1,min-dungeon[i][j]);
                }
            }
        }
        return dp[0][0];
    }