# Dynamic programming method (leetcode classic case analysis)

Time：2020-5-27

Today, let’s summarize some classic topics about dynamic planning on leetcode:

• `Best time to buy and sell stock`
• `House robber (maximum amount of robbery)`
• `Integer break`
• `Minimum path sum`
• `Triangle`

## Best time to buy and sell stock

Title: if you are only allowed to complete one transaction at most (i.e. buy one share, sell one share), design an algorithm to find the maximum profit

Example 1:
Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

### code implementation

``````public int maxProfit(int[] prices) {

int ans = 0;
if (prices.length == 0) {
return ans;
}

int bought = prices;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > bought) {
if (ans < (prices[i] - bought)) {
Ans = prices [i] - right; // find the maximum profit
}
} else {
Bought = prices [i]; // find the minimum cost
}
}
return ans;
}``````

## House robber (maximum amount of robbery)

Title: given an array of integers to represent a series of consecutive houses with money in them, the maximum amount that can be grabbed can be found when the adjacent houses cannot be entered consecutively to grab money.
Example :
Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.

### `Solutions to problems`

1. There is only one house nums , the maximum income is DP  = nums ;
2. There are two houses, nums , nums , which cannot be taken at the same time. The maximum income is DP  = max (nums , nums );
3. There are three houses with two methods: nums , or nums  and nums . That is DP  = max (nums , nums  + nums );
4. Therefore, it can be inferred that the dynamic conversion equation is:dp[i] = max(nums[i] + dp[i-2], dp[i-1]);

### code implementation

``````public static int rob(int[] nums) {

if (nums == null ||  nums.length  ==0) throw new runtimeException ("illegal input");
if (nums.length == 1) return nums;
if (nums.length == 2) return nums > nums ? nums : nums;

int n = nums.length;
int[] rob = new int[n];
//Initialize rob  and rob 
rob = nums;
rob = nums > nums ? nums : nums;
//Equation: DP [i] = max (nums [i] + DP [I-2], DP [I-1])
for (int i = 2; i < n; i++) {
rob[i] = rob[i - 1] > rob[i - 2] + nums[i] ? rob[i - 1] : rob[i - 2] + nums[i];
}
return rob[n - 1];
}
}``````

## Integer break

Title: divide a number into the sum of several positive integers, and find the maximum value of the product of these positive integers
Input: 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.

### code implementation

``````class Solution {
//Dynamic planning: bottom-up
public static int integerBreak(int n) {
//Condition judgment
if (n <= 0)
Throw new runtimeException ("illegal input");
int[] dp = new int[n + 1];
Arrays.fill(dp, -1);
dp = 1;
//Calculate the value of DP  ~ DP [n]
for (int i = 2; i <= n; i++) {
//J means there are 1 ~ n-1 cutting methods (the first section is cut into [1, n-1], [2, n-2]... [n-1, 1])
for (int j = 1; j < i - 1; j++) {
dp[i] = max3(dp[i], j * (i - j), j * dp[i - j]);
}
}
return dp[n];
}
//Returns the maximum of three numbers
private static int max3(int a, int b, int c) {
return Math.max(Math.max(a, b), c);
}
}``````

## Minimum path sum

Topic: given a two-dimensional array, starting from the upper left corner, you can only move down or right each time to find the shortest path sum from the upper left corner to the lower right corner.
Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation: Because the path 1→3→1→1→1 minimizes the sum.

### `Solutions to problems`

1. If we are in the grid at the bottom right corner (it can also be imagined that the grid has only one grid), then the shortest path sum is the value in the grid
2. If we are in the last line, if we are row-1, then the minimum path sum from this point to the bottom right corner is the sum of the minimum path itself plus the lattice on its right to the bottom right corner
3. The last column and the last row are the same
4. For a common position, what is the minimum path sum to the bottom right corner? It is the minimum path sum of the right position and the bottom position plus its own value

### code implementation

``````public static int dpMinPath(int[][] a) {
//Condition judgment
if (a == null || a.length == 0 || a.length == 0) {
Throw new runtimeException ("illegal input! "";
}
int row = a.length;
int col = a.length;

//DP [i] [J] represents the shortest path from a [i] [J] to the lower right corner and
int dp[][] = new int[row][col];
dp = a;
//Fill first column
for (int i = 1; i < row; i++) {
dp[i] = a[i] + dp[i - 1];
}
//Fill first line
for (int i = 1; i < col; i++) {
dp[i] = a[i] + dp[i - 1];
}
//Others
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
dp[i][j] = a[i][j] + Math.min(dp[i - 1][j], dp[i][j - 1]);
}
}
return dp[row - 1][col - 1];
}
}``````

## Triangle

Topic: given a triangle, find the minimum path sum from top to bottom. You can move to each step of the adjacent number in the next row.
For example, given the following triangle

``````    
[3,4]
[6,5,7]
[4,1,8,3]``````

The minimum path sum from top to bottom is 11 ( 2 + 3 + 5 + 1 = 11).

### code implementation

``````public static int minimumTotal(List<List<Integer>> triangle) {
//Condition judgment
if (triangle == null || triangle.size() == 0)  return 0;
if (triangle.size() == 1) return triangle.get(0).get(0);

int[] dp = new int[triangle.size()];
//Traverse up from the last line
for (int i = triangle.size() - 1; i >= 0; i--) {
for (int j = 0; j < triangle.get(i).size(); j++) {
//DP [J] in the last line is the corresponding value
if (i == triangle.size() - 1) {
dp[j] = triangle.get(i).get(j);
} else {
//Starting from the penultimate row, DP [J] = the smaller of the lower left DP value and the lower right DP value + its own value
dp[j] = Math.min(dp[j], dp[j + 1]) + triangle.get(i).get(j);
}
}
}
return dp;
}``````