• 有限状态机


    股票买卖问题

    leetcode 121

    一次买入一次卖出,并获取最大利润,只要求返回最大利润
    只要记录介质目前为止的最低价格,并且计算截至目前为止的最大利润就行

    class Solution {
        public static int maxProfit(int[] prices) {
            int[] dp = new int[prices.length + 1];
            int minPrice = Integer.MAX_VALUE;
            for (int i = 1; i <= prices.length; i++) {
                minPrice = Math.min(minPrice, prices[i - 1]);
                dp[i] = Math.max(dp[i - 1], prices[i - 1] - minPrice);
            }
            return dp[prices.length];
        }
    
    }
    

    leetcode 122

    允许多次交易,但是不允许同时多笔交易

    public class L122_maxProfit2 {
        public static int maxProfit(int[] prices) {
            int[][] dp = new int[prices.length + 1][2];
            dp[0][1]= Integer.MIN_VALUE;
            for (int i = 1; i <= prices.length; i++) {
                dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i - 1]);
                dp[i][1] = Math.max(dp[i - 1][0] - prices[i - 1], dp[i - 1][1]);
            }
            return dp[prices.length][0];
        }
    
        public static void main(String[] args) {
            int[] prices = {7, 1, 5, 3, 6, 4};
            System.out.println(maxProfit(prices));
        }
    }
    
    

    leetcode 123

    允许最多两笔交易

    public class L123_maxProfit {
        public static int maxProfit(int[] prices) {
            int buyZero = 0;
            int buyOne = Integer.MIN_VALUE,SellOne = 0;
            int buyTwo = Integer.MIN_VALUE,SellTwo = 0;
            //一共五种状态
            // 0 0次买卖
            // 1 1次买
            // 2 1次卖
            // 3 2次买
            // 4 2次卖
            for (int i = 1; i <= prices.length; i++) {
                buyOne = Math.max(buyOne,buyZero-prices[i-1]);
                SellOne = Math.max(SellOne,buyOne+prices[i-1]);
                buyTwo = Math.max(buyTwo,SellOne-prices[i-1]);
                SellTwo = Math.max(SellTwo,buyTwo+prices[i-1]);
            }
            return SellTwo;
        }
    
        public static void main(String[] args) {
            int[] prices = {3, 3, 5, 0, 0, 3, 1, 4};
            System.out.println(maxProfit(prices));
        }
    }
    
    

    leetcode 188

    class Solution {
         public static int maxProfit(int k, int[] prices) {
            if(prices.length==0)return 0;
            int[][] sell = new int[prices.length + 1][k + 1];
            int[][] buy = new int[prices.length + 1][k + 1];
            buy[0][0] = -prices[0];
            sell[0][0] = 0;
            for (int i = 1; i <= k; i++) {
                buy[0][i] = sell[0][i] = Integer.MIN_VALUE / 2;
            }
    
            for (int i = 1; i < prices.length; i++) {
                buy[i][0] = Math.max(buy[i - 1][0], sell[i - 1][0] - prices[i]);
                for (int j = 1; j <= k; j++) {
                    buy[i][j] = Math.max(buy[i - 1][j], sell[i - 1][j] - prices[i ]);
                    sell[i][j] = Math.max(sell[i - 1][j], buy[i - 1][j - 1] + prices[i]);
                }
    
            }
    
            int res = 0;
            for (int i = 0; i < sell[0].length; i++) {
                res = Math.max(res, sell[prices.length - 1][i]);
            }
            return res;
        }
    }
    

    leetcode 309

    单股票买卖不限制交易次数,带冷冻期

    public class L309_maxProfit {
        public static int maxProfit(int[] prices) {
            //f[i][0] 目前持有一只股票的累计最大收益
            //f[i][1] 目前不持有股票,且处于冷冻期的累计最大收益
            //f[i][2] 目前不持有股票,且不处于冷冻期的累计最大收益
            int N = prices.length;
            int[][] f = new int[N + 1][3];
            f[0][0] = -prices[0];
            for (int i = 1; i <= N; i++) {
                //目前持有一只股票,两种来源 上一天持有股票不动,或者来自于非冷冻期的上一天
                f[i][0] = Math.max(f[i - 1][0], f[i - 1][2] - prices[i - 1]);
                //目前不持有股票,且处于冷冻期 上一天持有并卖掉
                f[i][1] = f[i - 1][0] + prices[i - 1];
                //目前不持有股票,且不处于冷冻期, 来源上一天非冷冻期,或者上一天冷冻期
                f[i][2] = Math.max(f[i-1][1],f[i-1][2]);
            }
    
            return Math.max(f[N][1],f[N][2]);
        }
    
        public static void main(String[] args) {
            int[] prices = {1, 2, 3, 0, 2};
            System.out.println(maxProfit(prices));
        }
    }
    
    

    leetcode 714

    不限交易次数,带手续费

    public static int maxProfit(int[] prices, int fee) {
            int N = prices.length;
            int[] buy = new int[N + 1];
            int[] sell = new int[N + 1];
            buy[0] = -prices[0];
            for (int i = 1; i <= N; i++) {
                //截止目前持有一只股票的最大收益
                buy[i] = Math.max(buy[i - 1], sell[i - 1] - prices[i - 1]);
                //截止目前不持有股票的累计最大收益
                sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i - 1] - fee);
            }
            
            return sell[N];
        }
    
    

    I'm a fucKing fake coder!

  • 相关阅读:
    Day1-while and for/break and continue
    Day1-用户输入及字符串格式化输入
    Day1-python基础
    2-21-源码编译搭建LNMP环境
    2-20-使用apache搭建web网站
    2-19-mysql优化
    2-18-搭建mysql集群实现高可用
    2-17-MySQL读写分离-mysql-proxy
    2-16-2MySQL主从
    2-14-存储过程-触发器-事务
  • 原文地址:https://www.cnblogs.com/zhouyu0-0/p/15263126.html
Copyright © 2020-2023  润新知