Article directory
Dynamic programming (path problem)
1. Different paths |
-
status indication
dp[i][j]
Indicates how many paths there are when ending with i, j -
state transition equation
-
initialization
The place of initialization adopts the method of virtual node. The value in the auxiliary node must ensure that the subsequent form filling is correct, and the subscript mapping relationship must be correct
Here you must ensure that there is a place in the shaded part that is 1, so that you can ensure that the initialization is correct
-
fill in the form
top to bottom, left to right
-
return value
AC code:
class Solution
{
public:
int uniquePaths(int m, int n)
{
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
dp[0][1] = 1;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m][n];
}
};
2. Different paths||
-
status indication
dp[i][j]
Indicates how many paths there are to i, j positions -
state transition equation
If it is an obstacle, there is no need to process the node position,
-
initialization
Initialization, still using the auxiliary node method
-
fill in the form
top to bottom, left to right
-
return value
AC code:
class Solution
{
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid)
{
int m = obstacleGrid.size(), n = obstacleGrid[0].size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
dp[0][1] = 1;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if (obstacleGrid[i - 1][j - 1] == 0)
{
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m][n];
}
};
3. The maximum value of the gift
-
status indication
dp[i][j]
Indicates the maximum value when reaching i, j position -
state transition equation
-
initialization
Still use the virtual node method to initialize. Here you only need to initialize the values in the virtual node to 0.
-
fill in the form
top to bottom, left to right
-
return value
AC code:
class Solution
{
public:
int maxValue(vector<vector<int>>& grid)
{
int m = grid.size(), n = grid[0].size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
}
}
return dp[m][n];
}
};
4. Descent minimum sum
-
status indication
dp[i][j]
Represents the minimum sum at position i, j -
state transition equation
-
initialization
Here the virtual node needs to add one row and two columns
-
fill in the form
top to bottom, left to right
-
return value
the minimum value of the last row
AC code:
class Solution
{
public:
int minFallingPathSum(vector<vector<int>>& matrix)
{
int m = matrix.size();
vector<vector<int>> dp(m + 1, vector<int>(m + 2, INT_MAX));
for (int j = 0; j < m + 2; j++)
{
dp[0][j] = 0;
}
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= m; j++)
{
dp[i][j] = min(min(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + matrix[i - 1][j - 1];
}
}
int ret = INT_MAX;
for (int j = 1; j <= m; j++)
{
ret = min(ret, dp[m][j]);
}
return ret;
}
};
5. Minimum path sum
-
status indication
dp[i][j]
When representing i, j position, the minimum path sum -
state transition equation
-
initialization
Virtual nodes for easy initialization
-
fill in the form
-
return value
AC code:
class Solution
{
public:
int minPathSum(vector<vector<int>>& grid)
{
int m = grid.size(), n = grid[0].size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
dp[0][1] = dp[1][0] = 0;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
}
}
return dp[m][n];
}
};
6. Dungeon Game
-
status indication
If the minimum number of health points required to end with the i, j position is represented as a state, the following nodes will also affect the value of this node. So ending with a certain position cannot solve this problem very well. Change a state to indicate:
i, j
If you think that you start to reach the required health points at the end, you can solve this problem very well -
state transition equation
dp[i][j] + d[i][j] >= dp[i][j + 1]
, it should be noted that when it is a negative number, it needs to be changed to 1
-
initialization
-
fill in the form
Bottom to top, right to left
-
return value
AC code:
class Solution
{
public:
int calculateMinimumHP(vector<vector<int>>& dungeon)
{
int m = dungeon.size(), n = dungeon[0].size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
dp[m][n- 1] = dp[m- 1][n] = 1;
for (int i = m - 1; i >= 0; i--)
{
for (int j = n - 1; j >= 0; j--)
{
dp[i][j] = min(dp[i][j + 1], dp[i + 1][j]) - dungeon[i][j];
dp[i][j] = max(1, dp[i][j]);
}
}
return dp[0][0];
}
};