当前位置: 首页 > news >正文

力扣-股票买入问题

dp

dp元素代表最大利润

f[j][1] 代表第 j 次交易后持有股票的最大利润。在初始状态,持有股票意味着你花钱买入了股票,此时的利润应该是负数(扣除了买入股票的成本),而不是 0。所以,把 f[j][1] 初始化为负无穷大

f[j][0] 表示第 j 次交易完成后未持有股票的最大利润。当还未开始进行任何有效的股票买卖操作时,也就是处于初始状态,此时没有持有股票且利润为 0 

所以有了如下初始化

for (int j = 0; j < k + 2; j++) {
            for (int l = 0; l < 2; l++) {
                f[j][l] = Double.NEGATIVE_INFINITY;
            }
        }
// 初始化状态,第 j 次交易未持有股票时利润为 0
 for (int j = 1; j < k + 2; j++) {
    f[j][0] = 0;
}

 

因为可以交易0~k次,一共k+1种选择,而i = 0时,状态转移会出现i=-1的dfs,所以要开辟k+2个空间,而我们实际填写k+1种

因为数组不能有-1的索引,所以整体偏移,用0代表-1,1代表0.所以j<0而不是j<=0

import java.util.List;

public class StockTrading {
    public int maxProfit(List<Integer> prices) {
        // 最多允许的交易次数
        int k = 2;
        // 初始化动态规划数组 f
        double[][] f = new double[k + 2][2];
        for (int j = 0; j < k + 2; j++) {
            for (int l = 0; l < 2; l++) {
                f[j][l] = Double.NEGATIVE_INFINITY;
            }
        }
        // 初始化状态,第 j 次交易未持有股票时利润为 0
        for (int j = 1; j < k + 2; j++) {
            f[j][0] = 0;
        }
        // 遍历每一天的股票价格
        for (int i = 0; i < prices.size(); i++) {
            int p = prices.get(i);
            // 从后往前更新状态
            for (int j = k + 1; j > 0; j--) {
                // 更新第 j 次交易未持有股票的最大利润
                f[j][0] = Math.max(f[j][0], f[j][1] + p);
                // 更新第 j 次交易持有股票的最大利润
                f[j][1] = Math.max(f[j][1], f[j - 1][0] - p);
            }
        }
        // 返回最终结果,即最后一次交易未持有股票的最大利润
        return (int) f[f.length - 1][0];
    }
}

有冷冻期

修改状态转移方程

因为卖出的股票不能是前一天买入的了,所以不能-1要用合理时间的股票  

交易次数必须为2

只需要不断维护两次交易的利润即可,不需要记录全部交易的利润

这里不用开辟k+2的空间了,因为规定必须交易两次,所以状态转移方程没有变量了,而是具体的1和2,就不会出现-1的情况

import java.util.List;

public class StockTrading {
    public int maxProfit(List<Integer> prices) {
        // 交易次数必须为2次
        int k = 2;

        // 初始化动态规划数组 f
        // f[j][0] 表示第 j 次交易未持有股票的最大利润
        // f[j][1] 表示第 j 次交易持有股票的最大利润
        int[][] f = new int[k + 1][2];

        // 初始化状态
        for (int j = 1; j <= k; j++) {
            f[j][0] = Integer.MIN_VALUE; // 初始时,未持有股票的利润为最小整数
            f[j][1] = Integer.MIN_VALUE; // 初始时,持有股票的利润为最小整数
        }
        f[0][0] = 0; // 第0次交易未持有股票的利润为0

        // 遍历每一天的股票价格
        for (int i = 0; i < prices.size(); i++) {
            int p = prices.get(i);

            // 更新第 2 次交易的状态
            f[2][0] = Math.max(f[2][0], f[2][1] + p); // 第 2 次交易未持有股票
            f[2][1] = Math.max(f[2][1], f[1][0] - p); // 第 2 次交易持有股票

            // 更新第 1 次交易的状态
            f[1][0] = Math.max(f[1][0], f[1][1] + p); // 第 1 次交易未持有股票
            f[1][1] = Math.max(f[1][1], -p); // 第 1 次交易持有股票
        }

        // 返回最终结果,即第 2 次交易未持有股票的最大利润
        // 如果无法完成两次交易,返回 0 或其他特殊值
        return Math.max(f[2][0], 0); // 确保不会返回负值
    }
}

网课:买卖股票的最佳时机【基础算法精讲 21】_哔哩哔哩_bilibili

相关文章:

  • 骑砍Ⅱ霸主MOD开发(27)-定制化GameEntity-MissionWeapon
  • 【Manus】AI 代理人正式上岗-附Manus邀请码限时通道
  • 2.2 Windows本地部署DeepSeek模型 --- Ollama篇(下)
  • Training-free Neural Architecture Search for RNNs and Transformers(预览版本)
  • 基于Rye的Django项目通过Pyinstaller用Github工作流简单打包
  • [原创](Modern C++)现代C++的关键性概念: 非常独特的std::sentinel_for概念(哨兵概念)
  • LeetCode Hot100刷题——反转链表(迭代+递归)
  • 【c++】反转字符串
  • 二次SQL注入
  • 线程安全问题(面试重难点)
  • Python asyncIO 面试题及参考答案 草
  • 【数据结构与算法】Java描述:第二节:LinkedList 链表
  • Python 数据可视化
  • Python包结构与 `__init__.py` 详解
  • FusionInsight MRS云原生数据湖
  • Python贝壳网二手小区数据爬取(2025年3月更)
  • Python教学:语法检测问题-由DeepSeek产生
  • 30-判断子序列
  • Educational Codeforces Round 7 F. The Sum of the k-th Powers 多项式、拉格朗日插值
  • 浏览器信息收集插件之 雪瞳 —— 洞悉无形,守护无界
  • 哪些网站可以医生做兼职/宣传链接怎么做
  • wordpress添加背景图/搜狗seo优化
  • 网站搭建功能需求/个人主页网页设计
  • 东莞网站优化的具体方案/哈尔滨seo网络推广
  • 济南网站推广公司/谷歌搜索引擎为什么国内用不了
  • b建设银行网站首页/产品策划方案怎么做