DP of algorithm — trading stocks

Time:2020-11-7

I have always been afraid of dynamic programming problems. When I do this kind of problems, I always feel that I can’t do anything about it. I give up after thinking for a while, and then I go to the comment area to carry out my “bring” principle. In the end, I still don’t really understand it. No way. The best way to overcome fear is to face it. At present, we can only use the simplest understanding to solve such problems, including the previous collection of autumn leaves?

1. The best time to buy and sell stocks

Given an array, its i-th element is the price of a given stock on day I. If you are allowed to complete at most one transaction (that is, to buy and sell a stock once), design an algorithm to calculate the maximum profit you can make. Note: you can’t sell stocks before you buy them.

thinking

First of all, the most intuitive understanding:When traversing the entire array, each time it reaches a position, it judges the profit of the current stock if it is sold, and then updates the maximum value. In order to maintain the maximum profit, the minimum value of the current I position (excluding the current I) should be recorded as a buy.

The code is as follows:

public int maxProfit(int[] prices) {
        if (prices.length <= 1) {
            return 0;
        }
        int min = prices[0]; //Initialize to the first element of the array
        int max = 0;
        for (int i = 1; i < prices.length; i++) {
            max = Math.max(max, prices[i] - min); //If the current sale
            min = Math.min(min, prices[i]);       //Update minimum
        }
        return max;
    }

2. The best time to buy and sell stocks II

difficultysimple

Given an array, itsiAn element is a given stock numberiDays.

Design an algorithm to calculate the maximum profit you can make. You can do as many trades as you can.

be careful:You can’t participate in multiple transactions at the same time (you have to sell the previous stock before buying again).

thinking

Using dynamic programming, every time I arrive at an I position, there are only two states——Holding shares and not holding sharesSo each state can be determined by the previous state

The code is as follows:

public int maxProfit(int[] prices) {
        if (prices.length <= 1) {
            return 0;
        }
        int len = prices.length;
        int[][] dp = new int[len][2]; //DP [i] [0] means no holding on day I and DP [i] [1] holding on day I
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i = 1; i < len; i++) {
            dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
            dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
        }
        return dp[len - 1][0];
    }

3. The best time to buy and sell stocks III

Given an array, its i-th element is the price of a given stock on day I.

Design an algorithm to calculate the maximum profit you can make. You can complete up to two transactions.

Note: you cannot participate in more than one transaction at the same time (you must sell the previous stock before buying again).

thinking

Due to the limited number of transactions, theCan not be the same as the previous question unlimited transactions, at this time need to record the number of transactions this state.

The code is as follows:

 public int maxProfit(int[] prices) {
        if (prices.length <= 1) {
            return 0;
        }
        int k = 2;
        int[][][] dp = new int[prices.length][k + 1][2];
        for (int i = 0; i < prices.length; i++) {
            for (int j = k; j > 0; j--) {
                if (i == 0) {
                    //On day I, there are still J times when there is no stock in hand. When I = 0, there is no stock in hand, and the maximum profit is 0
                    dp[0][j][0] = 0;
                    dp[0][j][1] = -prices[0];
                    continue;
                }
                //If you don't have any stocks today, compare max (you may not have stocks the day before, but if you sell them today, you will have profits, so + prices [i])
                dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
                //If you have stocks in your hand today, compare max (you may have stocks the day before, but if you buy them today, you will have costs if you buy them today, so - prices [i])
                dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
            }
        }
        return dp[prices.length - 1][k][0];
    }

4. The best time to buy and sell stocks IV

Given an array, its i-th element is the price of a given stock on day I.

Design an algorithm to calculate the maximum profit you can make. You can complete up to K transactions.

Note: you cannot participate in more than one transaction at the same time (you must sell the previous stock before buying again).

thinking

This question is the same as above, but we need to judge the size of K, and then convert it into infinite transactions or specified times of transactions

 public int maxProfit(int k, int[] prices) {
        if (prices.length <= 1) {
            return 0;
        }
        int n = prices.length;
        //When k is very large, it turns into infinite transactions
        if(k>=n/2) {
            int dp0=0,dp1=-prices[0];
            for(int i=1;i<n;++i) {
                int tmp = dp0;
                dp0 = Math.max(dp0,dp1+prices[i]);
                dp1 = Math.max(dp1,dp0-prices[i]);
            }
            return Math.max(dp0,dp1);
        }
        int[][][] dp = new int[prices.length][k + 1][2];
        for (int i = 0; i < prices.length; i++) {
            for (int j = k; j > 0; j--) {
                if (i == 0) {
                    //On day I, there are still J times when there is no stock in hand. When I = 0, there is no stock in hand, and the maximum profit is 0
                    dp[0][j][0] = 0;
                    dp[0][j][1] = -prices[0];
                    continue;
                }
                //If you don't have any stocks today, compare max (you may not have stocks the day before, but if you sell them today, you will have profits, so + prices [i])
                dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
                //If you have stocks in your hand today, compare max (you may have stocks the day before, but if you buy them today, you will have costs if you buy them today, so - prices [i])
                dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
            }
        }
        return dp[prices.length - 1][k][0];
    }

This work adoptsCC agreementThe author and the link to this article must be indicated in the reprint