动态规划Day12(股票问题终结,有点疑惑)

这篇具有很好参考价值的文章主要介绍了动态规划Day12(股票问题终结,有点疑惑)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

309.最佳买卖股票时机含冷冻期

看到题目的第一想法               

看到代码随想录之后的想法

自己实现过程中遇到的困难

714.买卖股票的最佳时机含手续费

看到题目的第一想法               

看到代码随想录之后的想法

自己实现过程中遇到的困难


309.最佳买卖股票时机含冷冻期

力扣题目链接(opens new window)

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

示例:

  • 输入: [1,2,3,0,2]
  • 输出: 3
  • 解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
看到题目的第一想法
               

        回忆一下之前的股票问题是怎么做的?

        dp[i][0] 买入股票的最大现金

                        则为  之前买入的,当天买入的(用前一天的冷冻期来-)

                        Math.max(dp[i-1][0],dp[i-1][3]-prices[i]);

        dp[i][1] 卖出股票的最大现金

                        Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);

        我考虑加上一个 dp[i][3] 当天若为冷冻期的现金 

                        则直接为dp[i-1][1],不管是不是冷冻期都默认为dp[i-1][1]

        

看到代码随想录之后的想法

             代码随想录分析思路更加详细

         dp[i][j]:j有四种情况

         一. dp[i][0] 买入股票的最大现金

                1之前买入 dp[i-1][0]

                2当天买入

                        1 当天之前是冷冻期

                                dp[i-1][3]-price[i]  

                      2 当天之前不是冷冻期

                               dp[i-1][1]-price[i]

             二. dp[i][1] 之前卖出的最大现金

                1 当天之前是冷冻期

                        dp[i-1][3]

                2 当天之前不是冷冻期

                        dp[i-1][1]

              三.dp[i][2] 当天卖出的最大现金

                       dp[i-1][0]+prices[i]

              四. dp[i][3] 冷冻期的最大现金代码

                        则为前一天卖出的最大现金 dp[i-1][2]

        

        打印dp数组时,应该为 Math.max(dp[i][2],dp[i][3],dp[i][4])

自己实现过程中遇到的困难

        卡哥的做法:需要理清卡哥给的关系

        打印dp的值需要注意

class Solution {
    public int maxProfit(int[] prices) {
        /*
        //买入,卖出,冷冻期,买入,卖出,冷冻期
        //题意是要算出最大利润,但是需要尽可能地完成多的交易?
        //定义dp数组和每个下标的含义
        //冷冻期的最大金额?
        // dp[i][j] dp[i][0] 买入的最大金额,
        // dp[i][1]卖出的最大金额,
        // dp[i][2]冷冻期的最大金额
        //定义递推公式
        //冷冻期的最大金额-price[i]
        //dp[i][0] 买入时的最大值Math。max(dp[i-1][0],dp[i-1][2]-price[i]);
        //dp[i][1] 卖出时的最大值Math。max(dp[i-1][1],dp[i-1][0]+price[i]);
        //dp[i][2] 冷冻期 dp[i-1][1]
        //dp数组初始化
        //确定遍历顺序
        //从左至右
        //举例推导dp数组
        int[][] dp = new int[prices.length][3];
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[0][2] = 0;
        for(int i=1;i<prices.length;i++){
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][2]-prices[i]);
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);
            dp[i][2] = dp[i-1][1];
        }
        return dp[prices.length-1][1];*/
        //我的做法不够细致,有些地方模棱两可,没有卡哥思路写的那么清晰
        //卡哥思路:
        //一天存在的状态
        //1 买入股票
        //  1 当天买入,前一天为冷冻期 dp[i-1][3]+prices[i]
        //  2 当天买入,前一天不为冷冻期 dp[i-1][1]+prices[i]
        //  3 之前就买入 dp[i-1][0]
        //2 之前卖出股票
        //  1 若当天之前为冷冻期
        //  dp[i-1][3]
        //  2 若当天之前不为冷冻期
        //  dp[i-1][1]
        //3 当天卖出股票
        //  dp[i-1][0]+prices[i]
        //4 当天为冷冻期
        //  dp[i-1][2]
        //初始化
        //dp[0][0] = -price[i] 其他都为0,看dp的递推公式,应该都赋值为0
        //遍历顺序,从前往后
        int[][] dp = new int[prices.length][4];
        dp[0][0] = -prices[0];
        for(int i=1;i<prices.length;i++){
            //前一天为冷冻期,前一天不为冷冻期
            dp[i][0] = Math.max(Math.max(dp[i-1][3]-prices[i],dp[i-1][1]-prices[i]),dp[i-1][0]);
            //之前卖出,要考虑前一天是冷冻期or不是冷冻期
            dp[i][1] = Math.max(dp[i-1][3],dp[i-1][1]);
            //当天卖出
            dp[i][2] = dp[i-1][0]+prices[i];
            //当天为冷冻期,则前一天卖出
            dp[i][3] = dp[i-1][2];
        }
        
        //return 应该是123 之前写成了012 报错
        return Math.max(dp[prices.length-1][3],Math.max(dp[prices.length-1][1],dp[prices.length-1][2]));
    }
}

714.买卖股票的最佳时机含手续费

力扣题目链接(opens new window)

给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。

示例 1:

  • 输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
  • 输出: 8

解释: 能够达到的最大利润:

  • 在此处买入 prices[0] = 1
  • 在此处卖出 prices[3] = 8
  • 在此处买入 prices[4] = 4
  • 在此处卖出 prices[5] = 9
  • 总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

注意:

  • 0 < prices.length <= 50000.
  • 0 < prices[i] < 50000.
  • 0 <= fee < 50000.
看到题目的第一想法
               

        回忆一下之前的股票问题是怎么做的?

        dp[i][0] 买入股票的最大现金 减去相关的手续费即可

                        Math.max(dp[i-1][0],dp[i-1][3]-prices[i]-fee);

        dp[i][1] 卖出股票的最大现金

                        Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);

         1 应该怎么初始化?

        我的初始化是

        dp[0][0] = -prices[0]-fee

        dp[0][1] = dp[0][0]+prices[0](是有问题的)

        

看到代码随想录之后的想法

        代码随想录分析思路更加详细

         dp[i][j]:情况分析

        

        dp[i][0] 买入股票的最大现金

                        Math.max(dp[i-1][0],dp[i-1][3]-prices[i]);

        dp[i][1] 卖出股票的最大现金 加上相关的手续付费

                        Math.max(dp[i-1][1],dp[i-1][0]+prices[i]+fee);

        只需要初始化dp[0][0]=-prices[0]

        打印dp数组时,为什么是Math.max(dp[prices.length][0],dp[prices.length[1]]);

自己实现过程中遇到的困难

               不理解

                1初始化:dp[0][1]为何不用初始化

                2打印 :为何打印两个值?

 1:dp[0][1]对应的是第一天不持股的最佳状态,而不持股有两种可能性,可能是从开始就没有买过,也可能是买入又卖出,因此这里最佳应该是没有买过是 0,所以不用额外初始化


2:一般股票买卖的话,不持股状态下肯定比持有股票所得的现金多,没有问题。这个题应该是考虑到 fee 的存在,如果有一个 fee 特别大,那么可能就卖出不如不卖持有的现金多了,例如用例为 [1], 100 
但是因为不持股状态有不买不卖(也就是 0)这种情况的存在,使得最后的递推公式肯定不会推出负值,所以直接返回 不持股状态 就可以,没有任何问题文章来源地址https://www.toymoban.com/news/detail-816908.html

class Solution {
    public int maxProfit(int[] prices, int fee) {
        //需要算进去一个手续费用
        //买的时候需要加上手续费
        //确定dp数组以及每个下标的含义
        //dp[i][0] 买入股票的最大值 Math.max(dp[i-1][1]-prices[i]-2,dp[i-1][0]);
        //dp[i][1] 卖出股票的最大值 Math.max(dp[i-1][1],dp[i-1][0]+price[i]);
        //确定递推公式
        //dp数组初始化
        //dp[i][0]=-price[0];
        //确定遍历顺序
        //从前往后
        
        int[][] dp = new int[prices.length][2];
        dp[0][0]=-prices[0]-fee;
        dp[0][1]=0;
        for(int i=1;i<prices.length;i++){
            dp[i][0] = Math.max(dp[i-1][1]-prices[i]-fee,dp[i-1][0]);
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);
        }
        return Math.max(dp[prices.length-1][1],dp[prices.length-1][0]);
        
        /*
        int[][] dp = new int[prices.length][2];
        dp[0][0]=-prices[0];
        for(int i=1;i<prices.length;i++){
            dp[i][0] = Math.max(dp[i-1][1]-prices[i],dp[i-1][0]);
            //卡哥做法,卖出股票才付手续费 手续费为fee 之前写成了2
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]-fee);
        }
        return Math.max(dp[prices.length-1][1],dp[prices.length-1][0]);*/
    }
}

到了这里,关于动态规划Day12(股票问题终结,有点疑惑)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法基础复盘笔记Day09【动态规划】—— 背包问题

    ❤ 作者主页:欢迎来到我的技术博客😎 ❀ 个人介绍:大家好,本人热衷于 Java后端开发 ,欢迎来交流学习哦!( ̄▽ ̄)~* 🍊 如果文章对您有帮助,记得 关注 、 点赞 、 收藏 、 评论 ⭐️⭐️⭐️ 📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉 1. 题目

    2023年04月22日
    浏览(35)
  • 【算法日志】动态规划刷题:01背包问题,多重背包问题(day37,day38)

    目录 前言 目标和(01背包) 一和零(01背包) 零钱兑换(多重背包) 排列总和(多重背包) 这两天都是背包问题,其中的01背包的一些应用问题需要一定的数学建模能力,需要i将实际问题简化成我们熟悉的背包问题;而这两天的多重背包问题还算比较基础,但也要我明白了

    2024年02月11日
    浏览(37)
  • 【代码随想录】Day 49 动态规划10 (买卖股票Ⅰ、Ⅱ)

    https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/ dp[i]表示在第i天时,卖/不卖股票能获得的最大利润: 1、卖股票:dp[i] = prices[i] -minPrice(i天以前的最低价格) 2、不卖股票:dp[i] = dp[i-1](因为不卖股票,所以状态和前一天保持一致) ∴dp[i] = max(dp[i-1], prices[i] - minPrice); https

    2024年02月09日
    浏览(32)
  • 【LeetCode动态规划#12】详解买卖股票I~IV,经典dp题型

    力扣题目链接(opens new window) 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的最

    2023年04月24日
    浏览(45)
  • 研习代码 day42 | 动态规划——买卖股票的最佳时机 I II

            1.1 题目         给定一个数组  prices  ,它的第  i  个元素  prices[i]  表示一支给定股票第  i  天的价格。         你只能选择  某一天  买入这只股票,并选择在  未来的某一个不同的日子  卖出该股票。设计一个算法来计算你所能获取的最大利润。

    2024年02月03日
    浏览(29)
  • 算法[动态规划]---买卖股票最佳时机

    1、题目: 给你一个整数数组 prices,其中 prices[i] 表示某支股票第 i 天的价格。 在每一天,你可以决定是否购买和/或出售股票。你在任何时候最多只能持一股股票。你也可以先购买,然后在同一天出售。 返回你能获得的最大利润 。 2、 分析特点: 题目要求:在任何时候最多

    2024年02月09日
    浏览(32)
  • 【Day53】代码随想录之动态规划part10——买卖股票的最佳时机、买卖股票的最佳时机II

    昨天已经把打家劫舍的问题解决了,最后一个题目涉及到树形dp比较难(等到二刷的时候再重点看下),今天的任务是解决股票问题。 今日任务: 121.买卖股票的最佳时机 122.买卖股票的最佳时机II Leetcode题目:【121.买卖股票的最佳时机】 因为此题中买卖股票只能买卖一次。

    2024年03月15日
    浏览(83)
  • 力扣算法刷题Day42|动态规划:01背包问题 分割等和子集

    力扣题目:01背包问题(二维数组) 刷题时长:参考题解 解题方法:动态规划 + 二维dp数组 复杂度分析 时间 空间 问题总结 理解递推公式困难 本题收获 动规思路:两层for循环,第一层i遍历物品,第二层j枚举背包容量以内所有值 确定dp数组及下标的含义:dp[i][j] 表示从下标

    2024年02月13日
    浏览(41)
  • 力扣算法刷题Day44|动态规划:完全背包问题 零钱兑换II 组合总和Ⅳ

    力扣题目:#518.零钱兑换II(完全背包组合问题) 刷题时长:7min 解题方法:动态规划(完全背包) 复杂度分析 时间复杂度: O(mn),其中 m 是amount,n 是 coins 的长度 空间复杂度: O(m) 问题总结 对递推公式的理解 本题收获 题意转换:纯完全背包是凑成背包最大价值是多少,而本

    2024年02月13日
    浏览(31)
  • 【动态规划】简单多状态dp问题(2)买卖股票问题

    买卖股票问题 传送门:力扣309. 最佳买卖股票时机含冷冻期 题目: 1.1 题目解析 越难的dp问题,看示例只能起到了解题目的效果,一般推不出啥普遍的规律,所以接下来就是我们的算法原理,通过动归的思想去理解,才会豁然开朗! 1.2 算法原理 1.2.1 状态表示 我们需要通过经

    2024年02月12日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包