猜数字大小 II
力扣链接
力扣
题目描述:
我们正在玩一个猜数游戏,游戏规则如下:
- 我从
1到n之间选择一个数字。 - 你来猜我选了哪个数字。
- 如果你猜到正确的数字,就会 赢得游戏 。
- 如果你猜错了,那么我会告诉你,我选的数字比你的 更大或者更小 ,并且你需要继续猜数。
- 每当你猜了数字
x并且猜错了的时候,你需要支付金额为x的现金。如果你花光了钱,就会 输掉游戏 。
给你一个特定的数字 n ,返回能够 确保你获胜 的最小现金数,不管我选择那个数字 。

输入:n = 10 输出:16 解释:制胜策略如下: - 数字范围是 [1,10] 。你先猜测数字为 7 。- 如果这是我选中的数字,你的总费用为 $0 。否则,你需要支付 $7 。- 如果我的数字更大,则下一步需要猜测的数字范围是 [8,10] 。你可以猜测数字为 9 。- 如果这是我选中的数字,你的总费用为 $7 。否则,你需要支付 $9 。- 如果我的数字更大,那么这个数字一定是 10 。你猜测数字为 10 并赢得游戏,总费用为 $7 + $9 = $16 。- 如果我的数字更小,那么这个数字一定是 8 。你猜测数字为 8 并赢得游戏,总费用为 $7 + $9 = $16 。- 如果我的数字更小,则下一步需要猜测的数字范围是 [1,6] 。你可以猜测数字为 3 。- 如果这是我选中的数字,你的总费用为 $7 。否则,你需要支付 $3 。- 如果我的数字更大,则下一步需要猜测的数字范围是 [4,6] 。你可以猜测数字为 5 。- 如果这是我选中的数字,你的总费用为 $7 + $3 = $10 。否则,你需要支付 $5 。- 如果我的数字更大,那么这个数字一定是 6 。你猜测数字为 6 并赢得游戏,总费用为 $7 + $3 + $5 = $15 。- 如果我的数字更小,那么这个数字一定是 4 。你猜测数字为 4 并赢得游戏,总费用为 $7 + $3 + $5 = $15 。- 如果我的数字更小,则下一步需要猜测的数字范围是 [1,2] 。你可以猜测数字为 1 。- 如果这是我选中的数字,你的总费用为 $7 + $3 = $10 。否则,你需要支付 $1 。- 如果我的数字更大,那么这个数字一定是 2 。你猜测数字为 2 并赢得游戏,总费用为 $7 + $3 + $1 = $11 。 在最糟糕的情况下,你需要支付 $16 。因此,你只需要 $16 就可以确保自己赢得游戏。
解法:
1.记忆化递归:
简单地思路梳理:
我们可以枚举1到n中的每一个数字,记为x,那么分为两种情况,猜中了和没猜中
- 假如 x 正好是选中的数,那么,付出的代价为 0;
- 假如 x 不是选中的数,那么,付出的代价为 x,然后,我们会得到提示,选中的数比 x 大还是比 x 小:
- 假如比 x 小,我们只要求得 1 到 x-1 的最小代价,再加上 x 就能得到猜 x 时的最小代价;
- 假如比 x 大,我们只要求得 x+1 到 n 的最小代价,再加上 x 就能得到猜 x 时的最小代价;
- 而选中的数有可能在 x 的左边,也可能在 x 的右边,为了保证我们能够赢得游戏,我们需要备用的现金应该是左右两边的最小代价的最大值再加上 x 本身。
当我们枚举完这些 x 后,取其中的最小值就是我们需要备用的现金。
所以,我们可以得到递推公式:
你会发现存在很多重复的计算,比如,计算 f(1)(4) 的时候会计算 f(1)(2) 和 f(1)(3),而计算 f(1)(3) 的时候也会计算 f(1)(2),所以,我们可以加上缓存记录已经计算过的数值,这就是记忆化搜索
class Solution {public int getMoneyAmount(int n) {int[][] memo = new int[n + 2][n + 2];return dfs(1, n, memo);}private int dfs(int start, int end, int[][] memo) {if (start >= end) {return 0;}if (memo[start][end] != 0) {return memo[start][end];}int ans = Integer.MAX_VALUE;for (int k = start; k <= end; k++) {ans = Math.min(ans, Math.max(dfs(start, k - 1, memo), dfs(k + 1, end, memo)) + k);}return memo[start][end] = ans;}
}
2.动规(区间DP):
再上一步的记忆化递归中,我们发现,每次计算区间[x,y]都依赖与更小的区间,那么调整区间的计算顺序,我们不妨先计算小的区间,这样在计算大的区间的时候就不必重新计算小的区间了。
- 状态定义:dp[i][j]表示选中的数在 [i,j] 之间时能够确保获胜需要备用的现金数;
- 状态转移:dp[i][j]=min{k=i->j}(max(dp[i][k-1], dp[i][k+1]) + k);
- 初始值:对于只有一个数时,选中的数肯定就是这个数,代价为0,所以,初始值为 dp[i][i] = 0,Java中不需要特殊处理;
- 返回值:dp[1][n];
典型的区间dp的写法:
枚举长度从小到大:
class Solution {public int getMoneyAmount(int n) {// dp[i][j]表示选择的数在[i,j]之间时能够确保获胜的最小钱数// dp[i][j]=min{k=i->j}(max(dp[i][k-1], dp[i][k+1]) + k)int[][] dp = new int[n + 2][n + 2];for (int len = 2; len <= n; len++) {//长度从小到大枚举for (int i = 1; i <= n - len + 1; i++) {//从小到大,也就是举例 [1,1+len] [2,2+len]这样int j = i + len - 1;int min = Integer.MAX_VALUE;for (int k = i; k <= j; k++) {//注意k在后面的整体之中,为什么加k,因为是没选中k,所以要付出代价为k//然后比较原来的数据和当前没选中需要花费的最大的代价,取最大代价中最小的min = Math.min(min, Math.max(dp[i][k - 1], dp[k + 1][j]) + k);}dp[i][j] = min;}}return dp[1][n];}
}
代码说明:
注意,for循环中的len是我们枚举的长度,不是整个数字n的长度。
相关文章:
猜数字大小 II
力扣链接 力扣 题目描述: 我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字。你来猜我选了哪个数字。如果你猜到正确的数字,就会 赢得游戏 。如果你猜错了,那么我会告诉你,我选的数…...
CCNP350-401学习笔记(251-300题)
251、 Which IPv6 OSPF network type is applied to interface Fa0/0 of R2 by default? A. multipointB. broadcast C. Ethernet D. point-to-point 252、Which EIGRP feature allows the use of leak maps? A. neighborB. Stub C. offset-list D. address-family 253、W…...
掌握MySQL分库分表(二)Mysql数据库垂直分库分表、水平分库分表
文章目录垂直分表拆分方法举例垂直分库水平分表水平分库小结垂直角度(表结构不一样)水平角度(表结构一样)垂直分表 需求:商品表字段太多,每个字段访问频次不⼀样,浪费了IO资源,需要…...
算法训练营 day50 动态规划 单词拆分 多重背包理论基础
算法训练营 day50 动态规划 单词拆分 多重背包理论基础 单词拆分 139. 单词拆分 - 力扣(LeetCode) 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意:不要求字典中出现的单词…...
一文3000字用Postman从0到1实现UI自动化测试
“阅读本文大概需要4分钟。Postman不是做接口测试的吗?为什么还能做UI自动化测试呢? 其实,只要你了解Selenium的运行原理,就可以理解为什么Postman也能实现UI自动化测试了。 Selenium底层原理 运行代码,启动浏览器后…...
2023年美国大学生数学建模C题:预测Wordle结果建模详解+模型代码(一)
目录 前言 一、题目理解 背景 解析 字段含义: 建模要求 二、建模思路...
spring-boot 整合 前端框架 React 增删改查(附源码)
看了很多 关于 SpringBoot 增删改查 的文章 ,但是 React 前端框架这块似乎没什么人玩,一般都是Vue进行整合 ,所以想写一篇关于 React 整合 SpringBoot 增删改查的项目 React 学习区域 React中文教程: https://www.php.cn/doc/react/tutorial/…...
未来的城市:智慧城市定义、特征、应用、场景
智慧城市是通过连接一个地区的物理、经济和社会基础设施,以创新、有效和高效的方式应用和实施技术来发展城市的概念,以改善服务并实现更好的生活质量。智慧城市是一个将信息和通信技术融入日常治理的城市区域,旨在实现效率、改善公共服务、增…...
Qt线程池QThreadPool使用示例
目录前言1.线程池原理介绍2.QThreadPool详细介绍反复执行同一个任务设置线程过期时间线程数量信息3.QThreadPool示例4.总结前言 线程池顾名思义就是同时管理多个线程的"池子",它是一种并发处理技术,在程序中使用线程池能够提高线程的使用效率…...
【Spring】难理解的Aop编程 | 入门?
作者:狮子也疯狂 专栏:《spring开发》 坚持做好每一步,幸运之神自然会驾凌在你的身上 目录一. 🦁 前言二. 🦁 常见概念2.1 常见术语2.2 AOP入门Ⅰ. 🐇 功能场景Ⅱ. 🐇 实现过程2.3 通知类型Ⅰ.…...
2 月 25 日,论道京城 | 云原生开源项目应用实践报名开启
在数字化转型的浪潮中,云原生已经逐渐成为人们关注的焦点。开源社区作为云原生技术创新的根据地,为云原生的产业发展打造了丰富的技术生态圈,也在广泛的实践中源源不断地创造着新的机遇。想知道云原生存储技术实现了怎样的突破吗?…...
第五、六章 贪心算法、回溯算法
贪心算法 适合于贪心算法求解的问题具有:贪心选择性质、最优子结构性质。 贪心算法可以获取到问题的局部最优解,不一定能获取到全局最优解。 贪心算法总是作出在当前看来最好的选择;并且每次贪心选择都能将问题化简为一个更小的与原问题具有…...
k8s-kubectl命令
文章目录一、kubectl 基本命令1、陈述式资源管理方法:2、声明式资源管理办法二、基本信息查看三、项目的生命周期创建kubectl run命令四、金丝雀发布(Canary Release)——陈述式管理方法五、声明式管理方法kubectl create 和 kubectl apply区别一、kubectl 基本命令 1、陈述式…...
36、基于51单片机频率计 LCD 1602显示系统设计
摘要 数字频率计是一种基本的测量仪器。它被广泛应用于航天、电子、测控等领域,还被应用在计算机及各种数学仪表中。一般采用的是十进制数字,显示被测信号频率。基本功能是测量正弦信号,方波信号以及其他各种单位时间内变坏的物理量。由于其…...
【vue】elemente-ui table toggleRowSelection 默认选择无效[已解决]
项目场景: 点击按钮,弹出一个弹出框,内部出现一个table表,表内数据是动态获取,同时得勾选上几个table表的数据,类似以下的图 问题描述 点击按钮显示弹出框,加载table中的数据,默…...
SpringMVC DispatcherServlet源码(5) HttpMessageConverter扩展
前文通过阅读源码,深入分析了DispatcherServlet及相关组件的工作流程,本文不再阅读源码,介绍一下扩展HttpMessageConverter的方式。 HttpMessageConverter工作方式及扩展方式 前文介绍过,HttpMessageConverter是读写请求体和响应…...
day16_API
今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、String 三、StringBuffer&StringBuilder 四、日期 零、 复习昨日 见晨考 一、String String代表字符串,类,java程序中的所有字符串&…...
十二月券商金工精选
✦研报目录✦ ✦简述✦ 按发布时间排序 华宝证券 主动暴露的得与失—从Barra框架到私募指增因子分析方法 发布日期:2022-12-01 关键词:股票、Barra、风险暴露、指数增强 主要内容:本文针对私募指数增强产品的策略流程,设计…...
JUnit
Junit 简介 JUnit是一个开源的java单元测试框架,它是XUnit测试体系架架构的一种体现 是Java语言事实上的标准单元测试库真正的优势来自于JUnit所采作用的思想和技术,而不是框架本身。推动了单元测试、测试先行的编程和测试驱动的开发JUnit衍生了许多xUn…...
MySQL学习笔记4-乐观锁和悲观锁
1.定义 乐观锁和倍灌水是并发控制采用的技术手段,确保当多个数位同时对数据中同一数据存取时,不会破坏事物的隔离性、统一性和数据库统一性 乐观锁 假定不会发生并发冲突,只在提交操作时检测是否违反数据完整性 实现方式: 记录…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
