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

千问 LeetCode 1872.石子游戏 VIII public int stoneGameVIII(int[] stones)

这是一道经典的博弈论动态规划问题。我们需要结合前缀和与逆向思维来解决。 核心思路1. 游戏规则分析* 操作每次移除最左边的 x 个石子x 1获得这些石子的分数和并在最左边放一个价值为该和的新石子。* 本质无论怎么操作每次移除的石子实际上都是原数组的一个前缀。* 比如原数组是 [A, B, C, D]。* 如果 Alice 拿走前 2 个 [A, B]得分 AB数组变为 [AB, C, D]。* 接下来 Bob 如果拿走前 2 个 [AB, C]得分 ABC。注意这相当于 Bob 拿走了原数组的前 3 个元素的前缀和。* 结论游戏的过程就是双方轮流选择原数组的一个前缀和作为得分且选择的位置必须比上一次选择的位置更靠右。2. 动态规划定义设 prefix[i] 为前 i 个石子的价值之和前缀和。设 dp[i] 表示当游戏进行到必须从第 i 个石子下标 i之后开始选择前缀时当前先手玩家能获得的最大分数差当前玩家分数 - 对手分数。3. 状态转移对于 dp[i]当前玩家有两种选择1. 不选当前位置留给后面这相当于直接变成 dp[i1] 的状态但这在逻辑上通常合并到下一种情况考虑。2. 选择拿走前 k 个石子结束位置为 k其中 k i* 当前玩家得分prefix[k]。* 剩下的局面对手变成了先手从位置 k1 开始。* 对手的优势dp[k1]。* 当前玩家的净胜分prefix[k] - dp[k1]。我们要最大化这个净胜分。即dp[i] max(prefix[k] - dp[k1])其中 k 从 i 到 n-1。4. 优化直接计算上面的转移方程是 O(N^2)。我们可以发现dp[i] 其实依赖于后面所有 prefix[k] - dp[k1] 的最大值。我们可以维护一个后缀最大值 max_val。从后往前遍历dp[i] max_valmax_val max(max_val, prefix[i] - dp[i])特别注意题目规定第一次操作必须拿走至少 2 个石子x 1所以 Alice 的第一次选择不能只拿第 0 个石子她必须从下标 1 或更后面结束。因此最终答案是 dp[1]表示从下标 1 开始做决策或者说第一次操作至少覆盖到下标 1。 Java 代码实现class Solution {public int stoneGameVIII(int[] stones) {int n stones.length;// 1. 计算前缀和// prefix[i] 表示前 i 个石子的和 (stones[0]...stones[i-1])int[] prefix new int[n 1];for (int i 0; i i时的最大分差// 实际上我们只需要维护一个后缀最大值即可不需要完整的 dp 数组// 初始化如果只剩最后一个石子下标 n-1无法操作分差为 0// 但我们的状态定义是基于前缀和的结束位置。// 令 maxVal 表示 max(prefix[k] - dp[k]) 对于所有 k i// 从后往前推// 当 i n-1 时只能拿走所有剩余即整个前缀得分为 prefix[n]// 此时对手没得玩分差就是 prefix[n]int maxVal prefix[n];// 我们从 n-2 开始倒推因为 in-1 的情况已经作为初始值// 最终我们需要求的是 dp[1]因为第一次必须拿 x1即至少拿到下标 1for (int i n - 1; i 1; i--) {// 当前的 dp[i] 就是之前的 maxVal// 这里的逻辑是dp[i] max(prefix[k] - dp[k]) for k i// 但我们需要更新 maxVal 供 i-1 使用// 新的选择是拿走前 i 个得分 prefix[i]对手面对 i对手优势 dp[i]// 所以新产生的差值是 prefix[i] - maxVal (注意这里的 maxVal 其实是上一轮的 dp[i1] 这一层的最优解)// 修正逻辑// 我们用 maxVal 记录 max(prefix[k] - dp[k])// 当前 dp[i] maxVal// 然后更新 maxVal max(maxVal, prefix[i] - dp[i])int currentDp maxVal;maxVal Math.max(maxVal, prefix[i] - currentDp);}// 最后 maxVal 存储的是 i1 时的最优解因为循环最后更新了一次// 实际上上面的循环逻辑稍微有点绕我们用更清晰的写法// 重新梳理清晰版逻辑// dp[i] max(prefix[k] - dp[k]) for k i// 令 f[i] prefix[i] - dp[i]// 则 dp[i] max(f[k]) for k i// 我们维护 suffixMax max(f[k])int[] dp new int[n 1];// 边界dp[n] 0 (没石子了)// f[n] prefix[n] - 0 prefix[n]int suffixMax prefix[n];// 从 n-1 倒推到 1for (int i n - 1; i 1; i--) {dp[i] suffixMax;// 更新 suffixMax加入当前的 f[i]suffixMax Math.max(suffixMax, prefix[i] - dp[i]);}return dp[1];}} 简化后的最终代码class Solution {public int stoneGameVIII(int[] stones) {int n stones.length;// 1. 计算前缀和for (int i 1; i 1Alice 第一次至少拿 2 个即下标 0 和 1所以第一次操作至少结束于下标 1for (int i n - 2; i 1; i--) {// 当前这一步的最优解是max(之前的最优解, 拿走前 i 个 - 对手的最优解)// 这里的逻辑是dp[i] max(suffixMax)// 然后更新 suffixMax max(suffixMax, prefix[i] - dp[i])// 这里的 maxVal 实际上代表的是 dp[i1] 及其后续的最优值即后缀最大值// 当前玩家如果选择拿走到 i得分 stones[i]对手面临局面 i1 (实际上是 i1 开始的后缀)// 但我们的状态定义是maxVal 已经是后面所有选择中的最大值了// 修正// 当前 dp[i] maxVal// 新的候选值stones[i] - dp[i]// 更新 maxValint currentDp maxVal;maxVal Math.max(maxVal, stones[i] - currentDp);}return maxVal;}}⏱️ 复杂度分析* 时间复杂度O(N)只需要一次遍历计算前缀和一次倒序遍历计算 DP。* 空间复杂度O(1)如果允许修改原数组则不需要额外空间否则为 O(N) 用于前缀和。 关键点总结1. 前缀和每次操作本质上是取原数组的前缀和。2. 博弈 DPdp[i] max(score[k] - dp[k1])即“我拿的分数”减去“对手在剩余局面下的最优优势”。3. 后缀最大值优化避免 O(N^2) 的循环通过维护后缀最大值将复杂度降为 O(N)。4. 边界条件Alice 第一次必须拿 x1所以答案是从下标 1 开始计算的 dp[1]。

相关文章:

千问 LeetCode 1872.石子游戏 VIII public int stoneGameVIII(int[] stones)

这是一道经典的博弈论动态规划问题。我们需要结合前缀和与逆向思维来解决。🧠 核心思路1. 游戏规则分析 * 操作:每次移除最左边的 x 个石子(x > 1),获得这些石子的分数和,并在最左边放一个价值为该和的…...

10个提升数据科学效率的Python单行代码技巧

1. 10个提升数据科学工作流的Python单行代码作为一名数据科学家,我每天都要处理各种数据清洗、转换和分析任务。在多年的实践中,我发现Python的单行代码能极大提升工作效率。今天分享的这些技巧都是我在实际项目中反复验证过的,特别适合需要快…...

5G NR CSI数据集构建与感知算法实践

1. 项目概述:5G NR CSI数据集与感知应用在5G/6G通信系统中,信道状态信息(Channel-State Information, CSI)不仅是实现可靠通信的基础,更成为环境感知的关键数据源。传统上,CSI主要用于波束成形和链路自适应…...

毕业倒计时最后一周,别再傻傻查资料了!直接让 AI写作工具帮你搞定全文

还在为毕业论文熬夜查文献、改降重、调格式?距离截止只剩最后一周,时间紧、任务重,再用传统方式硬扛,大概率身心俱疲还难达标。聪明的学生早已用上 AI 写作工具,把一周的工作量压缩到几天,效率拉满、质量在…...

Java Agent与字节码增强:实现无侵入RASP与运行时诊断

1. 项目概述:从“黑盒”到“白盒”的运行时洞察革命在Java应用运维和安全的深水区,我们常常面临一个尴尬的境地:应用在线上跑得飞快,但内部究竟发生了什么,却像一个“黑盒”。传统的日志、APM(应用性能监控…...

注意力机制原理与优化:从MHA到GQA的演进

1. 注意力机制:语言模型理解上下文的核心在自然语言处理领域,让模型理解词语之间的关联关系一直是个关键挑战。想象一下这个句子:"The animal didnt cross the road because it was too tired." 要理解代词"it"指代的是&…...

C++26合约编程落地难点全突破(从预处理宏到运行时检查的7层验证机制)

更多请点击: https://intelliparadigm.com 第一章:C26合约编程落地难点全突破(从预处理宏到运行时检查的7层验证机制) C26 引入的合约(contracts)机制虽已通过 WG21 投票进入草案,但其实际落地…...

深度评测:GEO优化实战利器——爱搜索营销系统如何重塑企业在AI搜索时代的获客逻辑?

在ChatGPT、文心一言、豆包等大模型日益成为人们获取信息的第一入口时,一种全新的营销战场已经悄然铺开。传统SEO(搜索引擎优化)的逻辑正在被GEO(生成式引擎优化)快速迭代。对于企业而言,能否在AI大模型的“…...

【VSCode 2026国产化适配白皮书】:涵盖麒麟、统信、中科方德等6大OS内核级兼容方案(含实测性能衰减率<3.2%)

更多请点击: https://kaifayun.com 第一章:VSCode 2026国产化适配战略定位与白皮书核心结论 VSCode 2026版本已正式将“全栈国产化支持”列为一级战略目标,聚焦操作系统兼容性、芯片指令集适配、安全可信链构建三大支柱。其核心定位并非简单…...

深度评测:GEO优化软件源代码如何赋能本地生活服务企业?爱搜索实战验证报告

在AI搜索浪潮席卷之下,企业信息能否被ChatGPT、DeepSeek、豆包等大模型精准识别并推荐,已成为决定获客流量的关键。传统SEO的规则正在被改写,一种名为GEO(生成式引擎优化)的新范式应运而生。本文将以本地生活服务行业为…...

手写type_list_builder、auto_member_enumerator、compile_time_json_serializer——C++26反射三大高分代码题精讲(含CI验证用例)

更多请点击: https://intelliparadigm.com 第一章:C26 反射特性在元编程中的应用 面试题汇总 C26 正式引入了基于 std::reflexpr 的静态反射核心机制,使编译期类型信息可直接参与表达式计算,彻底摆脱了传统模板元编程中繁琐的 SF…...

PyTorch损失函数选择与优化实战指南

1. 理解损失函数的核心作用在PyTorch模型训练过程中,损失函数扮演着裁判员的角色。它量化了模型预测值与真实值之间的差距,就像考试评分标准一样告诉模型"错在哪里"和"错得多严重"。我刚开始接触深度学习时,曾错误地认为…...

英伟达破5万亿美元背后:数据分析师拆解AI投资逻辑(2026版)

前言 大家好,我是船长。 2026年4月25日,英伟达市值突破5万亿美元,费城半导体指数连续18个交易日上涨创下历史纪录。这是一个值得记录的历史时刻。 作为数据分析师,船长今天想从数据视角,带大家拆解这波AI行情背后的…...

SQL性能优化实战:从慢查询到秒开(详细代码注释)

前言 你写的SQL跑了30秒,老板催你,客户等着。 然后你把索引加上,1秒搞定。 这不是玄学,是有方法论的。 本文覆盖SQL性能优化最核心的5个方向: ✅ 读懂EXPLAIN执行计划 ✅ 索引的正确姿势(和常见误区&…...

Java开发者如何用LangChain4j构建RAG应用与智能体

1. 项目概述:为什么Java开发者需要LangChain4j?如果你是一名Java开发者,最近几个月肯定被各种AI和LLM(大语言模型)的消息刷屏了。从ChatGPT的对话到Claude的代码生成,再到本地部署的Llama,感觉全…...

微博开源分布式工作流引擎 rill-flow 核心架构与生产实践详解

1. 项目概述与核心价值最近在折腾工作流引擎,想找一个既轻量又功能强大的开源方案,试了一圈,最后把目光锁定在了weibocom/rill-flow这个项目上。你可能没听过这个名字,但说起它的“娘家”——微博,大家应该都不陌生。没…...

Stable Diffusion提示词优化7大进阶技巧

1. 项目概述:Stable Diffusion提示词进阶技巧解析"More Prompting Techniques for Stable Diffusion"这个标题直指AI绘画领域的核心痛点——如何通过优化提示词(prompt)获得更精准的生成结果。作为从业者,我深刻体会到提…...

为什么92%的量化研究员在VSCode里漏掉关键异常堆栈?——金融时间序列调试中的4层隐式上下文缺失分析

更多请点击: https://intelliparadigm.com 第一章:为什么92%的量化研究员在VSCode里漏掉关键异常堆栈?——金融时间序列调试中的4层隐式上下文缺失分析 被忽略的异常传播链 当使用 pandas.DataFrame.resample(5T).ohlc() 处理高频tick数据时…...

【2026企业级内存安全红线】:C语言开发者必须立即掌握的7大零容忍编码禁令

更多请点击: https://intelliparadigm.com 第一章:2026企业级内存安全红线的立法逻辑与合规基线 内存安全正从工程实践升维为法律义务。2026年起,欧盟《关键数字基础设施韧性法案》(CDIRA)与我国《关键信息基础设施内…...

php中的foreach循环?_?PHP中foreach循环的语法结构与遍历数组对象详解

...

如何确保多个 goroutine 的执行结果按启动顺序收集

...

Python季节性持续预测:时间序列分析的实用方法

## 1. 项目概述:当时间序列遇上季节性在零售销量预测、能源消耗预估、交通流量分析等领域,我们常会遇到具有明显季节性波动的数据。传统时间序列预测方法往往难以准确捕捉这种周期性规律,而基于Python的季节性持续预测(Seasonal P…...

怎样在宝塔面板高效管理几百个子站点_采用按分类标签化管理与批量操作插件

...

EvaDB:用SQL直接调用AI模型,实现数据库与AI的无缝集成

1. 项目概述:当数据库遇上AI,EvaDB想解决什么?如果你在过去几年里尝试过将AI模型,特别是那些大型语言模型或者复杂的计算机视觉模型,集成到你的数据应用里,那你大概率体会过那种“拧螺丝”的繁琐和“造轮子…...

Java Agent技术实战:无侵入获取Shiro密钥与注入内存马

1. 项目概述 在红队攻防演练和日常安全测试中,我们经常会遇到一些“卡脖子”的难题。比如,费尽周折拿到一个Webshell,却发现目标系统的数据库连接密码要么藏在某个晦涩的配置文件深处,要么被开发者用自定义逻辑加密了,…...

OpenAgents智能体框架:从ReAct模式到工具集成的工程实践

1. 项目概述:一个能“干活”的AI智能体框架最近在AI智能体这个圈子里,OpenAgents 这个项目讨论度挺高。简单来说,它不是一个只能和你聊天的AI,而是一个能真正“动手”帮你干活的AI助手框架。想象一下,你告诉它“帮我查…...

12天实现Transformer神经机器翻译:从原理到PyTorch实战

1. 项目概述:12天实现Transformer神经机器翻译器第一次接触Transformer架构时,我被它的注意力机制彻底震撼了——这种完全摒弃循环神经网络的全新结构,在机器翻译任务上实现了质的飞跃。这个12天速成项目将带您从零实现一个基于Transformer的…...

Python实现朴素贝叶斯分类器:从原理到优化

1. 项目概述:从零实现朴素贝叶斯分类器三年前我第一次用scikit-learn的GaussianNB时,就被这个算法在文本分类任务上的效率震惊了——准确率85%的同时训练速度比SVM快20倍。但直到自己动手实现,才真正理解其精妙之处。本文将带你用Python从零构…...

机器人锂电池的常见维护要注意什么?

机器人锂电池是机器人工作的“心脏”,它决定了机器人的续航能力、加速性能和工作稳定性。随着机器人智能化水平的提升,对电池性能的要求也日益提高,高效、安全的电池维护成为保障机器人稳定运行的重要保障。一、机器人锂电池的常见维护定期检…...

PUAX框架实战:基于RAG构建高效长文本智能问答系统

1. 项目概述与核心价值最近在折腾一些个人项目,需要处理大量非结构化文本数据,比如从网页上爬下来的文章、PDF文档里的内容,还有各种用户生成的评论。这些数据五花八门,格式不一,直接丢给模型处理效果总是不尽如人意。…...