(coordinate dynamic programming) leetcode difficulty 174. Dungeon game

topic

Some demons grabbed the princess (P) and locked her in the bottom right corner of the dungeon. A dungeon is a two-dimensional grid of M x N rooms. Our heroic knight (K) is initially placed in the upper left room and he has to travel through dungeons and save the princess by fighting demons.

A knight's initial health point is a positive integer. If his health points drop to 0 or below at some point, he dies instantly.

Some rooms are guarded by demons, so the knight will lose health points when entering these rooms (if the value in the room is a negative integer, the knight will lose health points); other rooms are either empty (the value in the room is 0) , or contains a magic orb that increases the knight's health points (if the value in the room is a positive integer, it means the knight will gain health points).

In order to get to the princess as quickly as possible, the knight decided to move only one step to the right or down at a time.

Write a function to calculate the minimum initial health points required to ensure that the knight can save the princess.

For example, considering a dungeon with the following layout, if the knight follows the optimal path right->right->down->down, the knight's initial health points should be at least 7.

insert image description hereillustrate:

There is no cap on the health points of a knight.

Any room may pose a threat to the knight's health points, and may also increase the knight's health points, including the upper left room where the knight enters and the lower right room where the princess is imprisoned.

Source: LeetCode
Link: https://leetcode-cn.com/problems/dungeon-game The
copyright belongs to LeetCode.com. For commercial reprints, please contact the official authorization, and for non-commercial reprints, please indicate the source.

analyze

It can be seen that it is a coordinate-based dynamic programming. The usual idea is to initialize the first row and column, and then calculate row by row. The last step is two choices, the upper and the left, choose the one with the smaller health value, If you think about it this way, this question is very simple
, but if you take a closer look, this question still has positive numbers, and you can add blood, so there is no way to calculate it like before,
so you can only calculate it from the bottom right to the top left (test from the top left to the bottom right). There are many ways to do this)

1. The last step

From the right or the bottom, then subtract the value of the current grid is the required value. Note that it needs to be compared with 1 because some grids are positive numbers, which may be less than 1 after subtraction, but the minimum health value we need is 1.

2. Transfer equation

f[i][j]=min(f[i+1][j]-current grid, f[i][j+1]-current grid) Note that the value here must be compared with 1, the minimum is 1

code section

1. Initialization

When initializing, it should be noted that any state must be considered less than 1, and it must be compared with 1. First initialize the last element, the last row and the last column

		if(dungeon.size()==0)
			return 0;
		int row=dungeon.size();
		int col=dungeon[0].size();
		vector<vector<int> > f(row,vector<int>(col)); 	//状态 
		
		f[row-1][col-1]=max(1,1-dungeon[row-1][col-1]);//初始化 
		for(int i=row-2;i>=0;--i)	
		{
    
    
			f[i][col-1]=max(1,f[i+1][col-1]-dungeon[i][col-1]);
		}
		
		for(int i=col-2;i>=0;--i)
		{
    
    
			f[row-1][i]=max(1,f[row-1][i+1]-dungeon[row-1][i]);
		}
2. Dynamic gauge core
		for(int i=row-2;i>=0;--i)		//动规核心 
			for(int j=col-2;j>=0;--j)
			{
    
    
				int minval=min(f[i+1][j],f[i][j+1]);
				f[i][j]=max(1,minval-dungeon[i][j]);
			}

full code

class Solution {
    
    
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
    
    
		if(dungeon.size()==0)
			return 0;
		int row=dungeon.size();
		int col=dungeon[0].size();
		vector<vector<int> > f(row,vector<int>(col)); 	//状态 
		
		f[row-1][col-1]=max(1,1-dungeon[row-1][col-1]);//初始化 
		for(int i=row-2;i>=0;--i)	
		{
    
    
			f[i][col-1]=max(1,f[i+1][col-1]-dungeon[i][col-1]);
		}
		
		for(int i=col-2;i>=0;--i)
		{
    
    
			f[row-1][i]=max(1,f[row-1][i+1]-dungeon[row-1][i]);
		}
		
		for(int i=row-2;i>=0;--i)		//动规核心 
			for(int j=col-2;j>=0;--j)
			{
    
    
				int minval=min(f[i+1][j],f[i][j+1]);
				f[i][j]=max(1,minval-dungeon[i][j]);
			}
		
		return f[0][0];
    }	
};

Summarize

Coordinate dynamic programming, my habit is to initialize one row and one column first, or put it directly into the state, and judge the first row and first column for assignment

Guess you like

Origin blog.csdn.net/weixin_46035615/article/details/124123418