# Some exercises of dynamic programming

Posted by nagrgk on Mon, 21 Feb 2022 07:31:36 +0100

# 1. Change

subject

```class Solution {
public int coinChange(int[] coins, int amount) {
int n = coins.length;
int[] arr = new int[amount + 1];// 0..amount

// Define initial conditions
arr[0] = 0;
for(int i = 1; i <= amount; i++) {
// Find arr[i]
arr[i] = Integer.MAX_VALUE;
for(int j = 0; j < n; j++) {
if(i >= coins[j] && arr[i - coins[j]] != Integer.MAX_VALUE && arr[i - coins[j]] + 1 < arr[i]) {
arr[i] = arr[i - coins[j]] + 1;
}

}
}
if (arr[amount] == Integer.MAX_VALUE) {
return -1;
}else {
return arr[amount];
}

}
}
```

# 2. Different paths - 1

subject

## analysis:

### The first step of dynamic planning: determine the status

a. The last step: no matter how the robot finally reaches the end, there are only two cases in the last step, that is, from left to right and from top to bottom. If the target position is [m - 1][n -1], it comes from [m-2][n-1] and [m - 1][n - 2].
b. Subproblem. The original problem is from [0] [0] to [m-1][n-1] into how many ways from [0] [0] to [m-2][n-1] and how many ways from [0] [0] to [m-1][n-2]

### The second step of dynamic programming: state transition equation

f[i][j] = f[i - 1][j] + f[i][j - 1]

### The third step of dynamic programming: initial conditions and boundary conditions

Initial condition: f[0][0] = 1
Boundary condition: when i = 0 or j = 0, you can only come from one direction, f [0] [J] = 1, f [i] [0] = 1

### Step 4 of dynamic programming: calculation sequence

Calculate row 0
Calculate line 1
. . .
Calculate line m - 1
The answer is f[m - 1][n -1]

```class Solution {
public int uniquePaths(int m, int n) {
int[][] arr = new int[m][n];
arr[0][0] = 1;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if (i == 0 || j == 0) {
arr[i][j] = 1;
}else{
arr[i][j] = arr[i][j - 1] + arr[i - 1][j];
}

}
}
return arr[m - 1][n - 1];
}
}
```

# 3. Different paths - 2

subject

## Analysis: the difference between this question and 1 is that the obstacle f[i][j] = 0, and then in the boundary conditions, the uppermost and leftmost are no longer directly equal to 1, but determined by the one in front of it!

### The first step of dynamic planning: determine the status

a. The last step: no matter how the robot finally reaches the end, there are only two cases in the last step, that is, from left to right and from top to bottom. If the target position is [m - 1][n -1], it comes from [m-2][n-1] and [m - 1][n - 2].
b. Subproblem, the original problem is to change from [0] [0] to [m-1][n-1] into how many ways from [0] [0] to [m-2][n-1] and how many ways from [0] [0] to [m-1][n-2]

### The second step of dynamic programming: state transition equation

f[i][j] = f[i - 1][j] + f[i][j - 1]

### The third step of dynamic programming: initial conditions and boundary conditions

Initial condition: f[0][0] = 1
Boundary conditions: i = 0 or j = 0, f [i] [J] = f [i] [J - 1] or f[i - 1][j]

### Step 4 of dynamic programming: calculation sequence

```class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[][] arr = new int[m][n];
if(obstacleGrid[0][0] == 1 || obstacleGrid[m - 1][n - 1] == 1) {
return 0;
}else{
arr[0][0] = 1;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(obstacleGrid[i][j] == 1) {
arr[i][j] = 0;
}else{
if(i == 0 && j == 0){
arr[i][j] = 1;
}else{
if(i == 0) {
arr[i][j] = arr[i][j - 1];
}
if(j == 0) {
arr[i][j] = arr[i - 1][j];
}
if(i != 0 && j != 0) {
arr[i][j] = arr[i - 1][j]+ arr[i][j - 1];
}
}
}
}
}
}

return arr[m - 1][n - 1];
}
}
```

# 4. Jumping game

subject

## analysis:

### The first step of dynamic planning: determine the status

a. The last step: no matter how you get to the last step, you will jump directly from the previous step
b. For the subproblem, it can jump to the last step j successfully. The last jump is successful in position i, and the number of steps that can jump in position i can reach j

### The second step of dynamic programming: state transition equation

f[j] = or{i = 0 to J-1} {f [i] & & nums [i] > J - I}

### The third step of dynamic programming: initial conditions and boundary conditions

Initial condition: f[0]= true
Boundary conditions: None

### Step 4 of dynamic programming: calculation sequence

From small to large.

```class Solution {
public boolean canJump(int[] nums) {
// There are two conditions for f[j] to be true
// 1. f[i] = true 2. nums[i] > j - i
if (nums == null || nums.length == 0) return false;
int n = nums.length;
boolean[] arr = new boolean[n+1];
arr[0] = true;

for(int i = 1; i < n; i++) {

arr[i] = false; // Here is a small detail
for(int j = 0; j < i; j++) {
if(arr[j] && nums[j] >= i - j) {
arr[i] = true;
break;
}
}

}
return arr[n - 1];
}
}
```

# 5. Paint the house

Paint the house 2. Please move to question 12
subject
analysis:
Sequential dynamic programming: first i minimum / number of modes / minimum
sequence ➕ state

```class Solution {
public int minCost(int[][] costs) {
int n = costs.length;// Number of houses
int[][] arr = new int[3][n];
//arr[0][i] represents the lowest price of the first I house when the I house is red
// arr[1][i] represents the lowest price of the first I house when the I house is blue
// arr[2][i] represents the lowest price of the first I house when the I house is green

// initial condition
for(int i = 0; i < 3; i++) {
arr[i][0] = costs[0][i];
}
for(int i = 1; i < n; i ++) {
arr[0][i] = arr[1][i - 1] > arr[2][i - 1] ? arr[2][i - 1] + costs[i][0]: arr[1][i - 1] + costs[i][0];
arr[1][i] = arr[0][i - 1] > arr[2][i - 1] ? arr[2][i - 1] + costs[i][1]: arr[0][i - 1] + costs[i][1];
arr[2][i] = arr[0][i - 1] > arr[1][i - 1] ? arr[1][i - 1] + costs[i][2]: arr[0][i - 1] + costs[i][2];
}
return getMin(arr[0][n - 1], arr[1][n - 1], arr[2][n - 1]);

}
public int getMin(int a, int b, int c) {
int temp = a>b?b:a;
return temp>c?c:temp;
}

}
```

# 6. Decoding method

subject

My solution is very verbose

```class Solution {
public int numDecodings(String s) {
if(s == null || s.charAt(0) == '0') {
return 0;
}else if(s.length() == 1 && s.charAt(0) != '0' ) {
return 1;
}else{
int n = s.length();
int[] arr = new int[n];
arr[0] = 1;

if(s.charAt(0) == '1' && s.charAt(1) != '0') {
// If the first one is 1 or 2
arr[1] = 2;
}else if(s.charAt(0) == '2'&& Character.getNumericValue(s.charAt(1)) <= 6 && s.charAt(1) != '0') {
arr[1] = 2;
}else if(Character.getNumericValue(s.charAt(0))>= 3&& s.charAt(1) == '0') {
// arr[1] = 0;
return 0;
}else if(s.charAt(0) == '0'&& s.charAt(1) == '0') {
return 0;
}
else{
arr[1] = 1;
}
for(int i = 2; i < n; i++){
if(s.charAt(i - 1) == '1' && s.charAt(i) != '0') {
// If the first one is 1 or 2
arr[i] = arr[i - 1] + arr[i - 2];
}else if(Character.getNumericValue(s.charAt(i - 1))>= 3 && s.charAt(i) == '0') {
// arr[1] = 0;
return 0;
}else if(s.charAt(i - 1) == '0' && s.charAt(i) == '0') {
return 0;
}
else if(s.charAt(i - 1) == '2' && Character.getNumericValue(s.charAt(i)) <= 6 && s.charAt(i) != '0') {
arr[i] = arr[i - 1] + arr[i - 2];
}else if(s.charAt(i - 1) == '1' && s.charAt(i) == '0'){
arr[i] = arr[i - 2];
}else if (s.charAt(i - 1) == '2' && s.charAt(i) == '0'){
arr[i] = arr[i - 2];
}else{
arr[i] = arr[i - 1];
}
}

return arr[n - 1];
}

}
}
```

A relatively simple and skilled solution

```class Solution {
public int numDecodings(String s) {
char[] ss = s.toCharArray();
int n = ss.length;
if (n == 0) {
return 0;
}
int[] arr = new int[n+1];
int m = ss[0] - '0';
arr[0] = 1;
for(int i = 1; i <= n; i++) {
arr[i] = 0;
int t = ss[i - 1] - '0';
if(t >= 1 && t <= 9){
arr[i] += arr[i - 1];
}
if(i >= 2) {
int q = ss[i - 2] - '0';
int p = ss[i - 1] - '0';
if(q * 10 + p >= 10 && q * 10 + p <= 26) {
arr[i] += arr[i - 2];// Learn well and wait
}
}

}
return arr[n];

}
}
```

# 7. Longest continuous increasing subsequence

Coordinate dynamic programming
subject

```class Solution {
public int findLengthOfLCIS(int[] nums) {
int n = nums.length;
if(n == 0) {
return 0;
}else{
int[] arr = new int[n];
arr[0] = 1;
int m = 1;
for(int i = 1;i < n; i++) {
if(nums[i]> nums[i - 1]){
arr[i] = arr[i - 1] + 1;
}else{
arr[i] = 1;
}
if(m <= arr[i]){
m = arr[i];
}
}
return m;
}

}
}
```

# 8. Minimum path and

subject

```class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] arr = new int[m][n];
arr[0][0] = grid[0][0];
for(int i = 1; i < m; i++) {
arr[i][0] = arr[i - 1][0] + grid[i][0];
}
for(int i = 1; i < n; i++) {
arr[0][i] = arr[0][i - 1] + grid[0][i];
}

for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
arr[i][j] = arr[i - 1][j] < arr[i][j - 1] ? grid[i][j] + arr[i - 1][j]: grid[i][j] + arr[i][j - 1];
}
}
return arr[m - 1][n - 1];

}
}
```

# 9. Bomb the enemy

subject

```public static int maxKillEnemies(char[][] A) {
if (A == null || A.length == 0 || A[0].length == 0) {
return 0;
}
int m = A.length;
int n = A[0].length;

int[][] f = new int[m][n];
int[][] res = new int[m][n];

for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
res[i][j] = 0;
}
}

// up
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (A[i][j] == 'W') {
f[i][j] = 0;
}else {
f[i][j] = 0;
if (A[i][j] == 'E') {
f[i][j] = 1;
}
if (i > 0) {
f[i][j] += f[i - 1][j];
}
}
res[i][j] += f[i][j];
}
}

// down
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
if (A[i][j] == 'W') {
f[i][j] = 0;
}else {
f[i][j] = 0;
if (A[i][j] == 'E') {
f[i][j] = 1;
}
if (i < m - 1) {
f[i][j] += f[i + 1][j];
}
}
res[i][j] += f[i][j];
}
}

// left
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (A[i][j] == 'W') {
f[i][j] = 0;
}else {
f[i][j] = 0;
if (A[i][j] == 'E') {
f[i][j] = 1;
}
if (j > 0) {
f[i][j] += f[i][j - 1];
}
}
res[i][j] += f[i][j];
}
}

// right
for (int i = 0; i < m; i++) {
for (int j = n - 1; j >= 0; j--) {
if (A[i][j] == 'W') {
f[i][j] = 0;
}else {
f[i][j] = 0;
if (A[i][j] == 'E') {
f[i][j] = 1;
}
if (j < n - 1) {
f[i][j] += f[i][j + 1];
}
}
res[i][j] += f[i][j];
}
}
int result = Integer.MIN_VALUE;

for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (A[i][j] == '0') {
result = result > res[i][j] ? result:res[i][j];
}
}

}

return result;
}
```

# 10. Yang Hui triangle

subject

```class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> dp = new ArrayList<List<Integer>>();
List<Integer> tmp = new ArrayList<Integer>();
if(numRows == 1) {
return dp;
}
List<Integer> tmp2 = new ArrayList<Integer>();
if(numRows == 2) {
return dp;
}

for(int i = 2; i < numRows; i++) {
List<Integer> t = new ArrayList<Integer>();
for(int j = 1; j < i; j++) {
t.add(dp.get(i - 1).get(j - 1) + dp.get(i - 1).get(j));
}
}
return dp;
}
}
```

# 11. Bit count

subject

```class Solution {
public int[] countBits(int n) {
if(n == 0) {
return new int[]{0};
}else{
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i++) {
dp[i] = dp[i >> 1] + i % 2;
}
return dp;
}

}
}
```

# 12. Painting the house 2

subject

```class Solution {
public int minCostII(int[][] costs) {
int n = costs.length; // n houses
int k = costs[0].length; // k colors
int[][] f = new int[n+1][k];
int min1, min2;
int j1 = 0;
int j2 = 0;

// dp[i][j] I house before painting, and i-1 house is the minimum cost of j color
for(int j = 0; j < k; j++) {
f[0][j] = 0;
}
for(int i = 1; i <= n; i++) {
//Minimum and sub minimum
min1 = min2 = Integer.MAX_VALUE;
for(int j = 0; j < k; j++) {
if(f[i - 1][j] < min1) {
min2 = min1;
j2 = j1;
min1 = f[i - 1][j];
j1 = j;
}else{
if(f[i - 1][j] < min2) {
min2 = f[i - 1][j];
j2 = j;
}
}
}
for(int j = 0; j < k; j++) {
if(j == j1) {
f[i][j] = costs[i - 1][j] + min2;
}else{
f[i][j] = costs[i - 1][j] + min1;
}
}
}
int res = Integer.MAX_VALUE;
for(int i = 0; i < k; i++) {
res = res < f[n][i] ? res : f[n][i];
}
return res;
}
}
```

# 13. House theft

subject

```class Solution {
public int rob(int[] nums) {
int n = nums.length;
if(n == 1){
return nums[0];
}else if(n == 2){
return Math.max(nums[0], nums[1]);
}else{
int[] f = new int[n];
f[0] = nums[0];
f[1] = Math.max(nums[0], nums[1]);
for(int i = 2; i < n; i++) {
f[i] = f[i - 2] + nums[i] > f[i - 1] ? f[i - 2] + nums[i] : f[i - 1];
}
return f[n - 1];

}
}
}
```

# 14. House theft 2

subject

```class Solution {
public int rob(int[] nums) {
int n = nums.length;
if (n == 1) {
return nums[0];
}else if(n == 2) {
return Math.max(nums[0], nums[1]);
}else if(n == 3){
return Math.max(nums[0], Math.max(nums[1], nums[2]));
}else{
int[][] f = new int[n][2];
f[0][0] = nums[0];
f[0][1] = 0;
f[1][0] = nums[0];
f[1][1] = nums[1];
f[2][0] = nums[0];
f[2][1] = Math.max(nums[1], nums[2]);

for(int i = 3; i < n; i++) {
f[i][0] = Math.max(f[i - 1][0], f[i - 2][0]+ nums[i - 1]);
f[i][1] = Math.max(f[i - 1][1], f[i - 2][1]+ nums[i]);
}
return Math.max(f[n - 1][0], f[n - 1][1]);
}

}
}
```

# 15. Maximum profit of shares

subject

```class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;

if(n <= 1) {
return 0;
}else {
int[] dp = new int[n];
dp[0] = 0;
int tmp = prices[0];
for(int i = 1; i < n; i++) {
if(tmp > prices[i]){
tmp = prices[i];
}
if(prices[i] < prices[i - 1]){
dp[i] = dp[i - 1];
}else{
dp[i] = Math.max(prices[i] - tmp, dp[i - 1]);
}
}
return dp[n - 1];
}

}
}
```

Topics: Algorithm Dynamic Programming