zoukankan      html  css  js  c++  java
  • 股票问题总结

    框架

    思路:
    明确dp数组的定义,dp[i][k][0]代表 第i天,至多交易K次,并且手上还有股票的最大利润
    明确选择:每天都有三种「选择」:买入、卖出、无操作,我们用 buy, sell, rest 表示这三种选择

    base case:
    dp[-1][k][0] = dp[i][0][0] = 0
    dp[-1][k][1] = dp[i][0][1] = -infinity
    
    状态转移方程:
    dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
    dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
    

    一次交易最大利润

    class Solution {
        public int maxProfit(int[] prices) {
            //base case初始状态 dp[-1][0]=0,dp[-1][1]=-99999
            int dp_i_0=0,dp_i_1=Integer.MIN_VALUE;
            //设置一个变量保存前一个状态,使时间复杂度O(1)
            int n=prices.length;
            for(int i=0;i<n;i++){
                //今天没有持股的情况
                dp_i_0=Math.max(dp_i_0,dp_i_1+prices[i]);
                //今天持股的情况
                dp_i_1=Math.max(dp_i_1,-prices[i]);
            }
            return dp_i_0;
    
        }
    }
    

    尽可能多的交易

    class Solution {
        public int maxProfit(int[] prices) {
    
            int n=prices.length;
            int dp_i_0=0,dp_i_1=Integer.MIN_VALUE;
            for(int i=0;i<n;i++){
                int tmp=dp_i_0;
                dp_i_0=Math.max(dp_i_0,dp_i_1+prices[i]);
                dp_i_1=Math.max(dp_i_1,tmp-prices[i]);
            }
            return dp_i_0;
            
        }
    }
    

    最多俩次交易

    法1

    class Solution {
        public int maxProfit(int[] prices) {
           
        int dp_i10 = 0, dp_i11 = Integer.MIN_VALUE;
        int dp_i20 = 0, dp_i21 = Integer.MIN_VALUE;
        for (int price : prices) {
            dp_i20 = Math.max(dp_i20, dp_i21 + price);
            dp_i21 = Math.max(dp_i21, dp_i10 - price);
            dp_i10 = Math.max(dp_i10, dp_i11 + price);
            dp_i11 = Math.max(dp_i11, -price);
        }
        return dp_i20;
        }
    }
    

    法2

    class Solution {
        public int maxProfit(int[] prices) {
            //dp[-1][k][0] = 0
            //dp[-1][k][1] = -infinity
            //dp[i][0][0] = 0
            //dp[i][0][1] = -infinity
        
        int max_k = 2;
        int n=prices.length;
        int[][][] dp = new int[n][max_k + 1][2];
        if(n==0) return 0;
        for (int i = 0; i < n; i++) {
            for (int k = max_k; k >= 1; k--) {
                if (i - 1 == -1) { 
                    /*处理 base case */ 
                    dp[0][k][0]=0;
                    dp[0][k][1]=-prices[0];
                    continue;
    
                }
                dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);
                dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);
            }
        }
        // 穷举了 n × max_k × 2 个状态,正确。
        return dp[n - 1][max_k][0];
    
        }
    }
    

    多次交易含冷冻期

    class Solution {
        public int maxProfit(int[] prices) {
    
            int n=prices.length;
            int dp_i_0=0,dp_i_1=Integer.MIN_VALUE;
            int dp_i_pre=0;//dp[i-2][0]
    
            for(int i=0;i<n;i++){
                int tmp=dp_i_0;
                dp_i_0=Math.max(dp_i_0,dp_i_1+prices[i]);
                dp_i_1=Math.max(dp_i_1,dp_i_pre-prices[i]);
                dp_i_pre=tmp;
            }
            return dp_i_0;
    
        }
    }
    

    多次交易含手续费

    class Solution {
        public int maxProfit(int[] prices, int fee) {
            int n=prices.length;
            int dp_i_0=0,dp_i_1=Integer.MIN_VALUE;
            
            for(int i=0;i<n;i++){
                int tmp=dp_i_0;
                dp_i_0=Math.max(dp_i_0,dp_i_1+prices[i]);
                dp_i_1=Math.max(dp_i_1,tmp-prices[i]-fee);
            }
            return dp_i_0;
    
        }
    }
    
  • 相关阅读:
    從 IC流程中探索數位工程師的風格--III
    從 IC流程中探索數位工程師的風格--II
    從 IC流程中探索數位工程師的風格--I
    producer and consumer concept ( II )
    producer and consumer concept ( I )
    是否long pulse 訊號一定要拿來做同步處理?不做同步處理可以嗎?
    module介面訊號的收斂與發散的思考
    恐龍版OS裏的哲學家問題的思考
    git创建与合并分支
    把CentOS启动进度条替换为详细信息
  • 原文地址:https://www.cnblogs.com/treasury/p/12864949.html
Copyright © 2011-2022 走看看