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

金启网站建设360收录入口

金启网站建设,360收录入口,做网站被坑,备案的网站 能拿来做仿站吗文章目录 375. 猜数字大小 II解题思路:暴搜 -> 记忆化搜索 375. 猜数字大小 II 375. 猜数字大小 II 我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字。你来猜我选了哪个数字。如果你猜到正确的数字,就会…

文章目录

  • 375. 猜数字大小 II
  • 解题思路:暴搜 -> 记忆化搜索

在这里插入图片描述

375. 猜数字大小 II

375. 猜数字大小 II

我们正在玩一个猜数游戏,游戏规则如下:

  1. 我从 1n 之间选择一个数字。
  2. 你来猜我选了哪个数字。
  3. 如果你猜到正确的数字,就会 赢得游戏
  4. 如果你猜错了,那么我会告诉你,我选的数字比你的 更大或者更小 ,并且你需要继续猜数。
  5. 每当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x 的现金。如果你花光了钱,就会 输掉游戏

给你一个特定的数字 n ,返回能够 确保你获胜 的最小现金数,不管我选择那个数字

示例 1:

在这里插入图片描述

输入: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 就可以确保自己赢得游戏。

示例 2:

输入:n = 1
输出:0
解释:只有一个可能的数字,所以你可以直接猜 1 并赢得游戏,无需支付任何费用。

示例 3:

输入:n = 2
输出:1
解释:有两个可能的数字 1 和 2 。
- 你可以先猜 1 。- 如果这是我选中的数字,你的总费用为 $0 。否则,你需要支付 $1 。- 如果我的数字更大,那么这个数字一定是 2 。你猜测数字为 2 并赢得游戏,总费用为 $1 。
最糟糕的情况下,你需要支付 $1 。

提示:

  • 1 <= n <= 200

解题思路:暴搜 -> 记忆化搜索

​ 首先这道题先搞清楚题意很重要,虽然我们很习惯性的会去想二分的猜数字,但是在这道题二分不是最优解,因为还得结合节点的值,二分只是确保平均的查找路径是最短的,但是不能确保拿到的是最小现金数,也就是说,这道题其实就是一个暴搜!

​ 但是因为递归树太麻烦了这道题,有太多的路径,所以下面我们将其抽象一下,就得到下图:

​ 其中左右子树是有很多路径的,该图只是简化了,在左右子树还得继续暴力枚举对应区间上的路径可能!

​ 那么既然是暴搜,我们就 dfs() 函数帮我们拿到能够确保获胜的最小现金数,因为涉及到区间分割,所以要传两个参数 leftright 作为区间的左右边界控制一下,然后返回值就是整型,不过很容易想到!

​ 此时当我们选了 i 元素之后,那么对于 i 元素来说,它的左右子树拿到的就是各自能获胜的最小现金数,此时细节来了,对于 i 整棵子树来说,此时的最小现金数应该是左右子树各自的最小现金数中的最大值

​ 这是因为左右子树拿到的最小现金数是保证左右子树各自能获胜而使用的最小现金数,但是对于 i 元素来说,是要看整体的,无论是走左边还是右边都必须要赢,所以就必须选择大的那个才符合要求,如下图所示:

在这里插入图片描述

​ 代码如下所示,最好结合代码和上面的解释一起理解:

class Solution {
public:int getMoneyAmount(int n) {return dfs(1, n);}int dfs(int left, int right){// 函数递归出口(left==right的时候说明肯定是找到了,此时也是返回0,不需要支付金额)if(left >= right) return 0;int ret = INT_MAX; // 记录最小现金数for(int i = left; i <= right; ++i) // 枚举区间所有元素的路径{int x = dfs(left, i - 1);int y = dfs(i + 1, right);ret = min(ret, i + max(x, y)); // 记得左右子树的最大值要加上i才算当前的现金数,然后再更新最小现金数}return ret;}
};

​ 虽然思路正确,但是这道题暴搜仍然会超时!

​ 很明显,因为是暴搜,不同子树之间存在大量重复的区间,所以我们可以用记忆化搜索优化,将这些出现过的区间的最小现金数记录到备忘录中,下次进入函数前先判断备忘录是否有记录该区间的最小现金数,有的话直接返回即可,大大的提高了效率!

​ 另外初始化备忘录的问题,其实我们 直接初始化为 0 即可,因为出现结果为 0 的情况只有在函数递归出口,所以我们可以将备忘录的判断放到函数递归出口的下面进行判断即可,省去了我们去初始化的操作!

class Solution {
private:int memory[201][201]; // 二维数组作为备忘录,元素值表示[i, j]区间的最小现金数
public:int getMoneyAmount(int n) {return dfs(1, n);}int dfs(int left, int right){// 函数递归出口if(left >= right) return 0;// 进入函数前先判断备忘录是否有记录该区间的最小现金数,有的话直接返回if(memory[left][right] != 0)return memory[left][right];int ret = INT_MAX; // 记录最小现金数for(int i = left; i <= right; ++i){int x = dfs(left, i - 1);int y = dfs(i + 1, right);ret = min(ret, i + max(x, y)); // 记得左右子树的最大值要加上当前的i才算当前的现金数,然后再更新最小现金数}// 出函数之前,将该区间的结果记录下来memory[left][right] = ret;return ret;}
};

在这里插入图片描述

http://www.dtcms.com/wzjs/242793.html

相关文章:

  • 房产网查询seo建站优化
  • 找公司做网站要注意什么问题2021最火营销方案
  • 做网站南宁站长之家seo工具包
  • 网站建设培训班沧州网站seo
  • 建设多用户网站广告投放平台
  • 西宁网络公司网站制作优化系统软件
  • 青海省公路建设管理局网站网页制作培训教程
  • 泰州 住房和城乡建设厅网站优化seo可以从以下几个方面进行
  • 做直播网站找哪家网站腾讯域名
  • 做网站 融资武汉网站竞价推广
  • 美国免费网站空间惠州关键词排名优化
  • 网站制作需要什么资料深圳做网站
  • 网站都是程序员做的吗cilimao磁力猫最新版地址
  • 做网站找哪家最好网站统计系统
  • 网站编辑岗位十大室内设计网站
  • 昆山商城网站建设可以免费推广的平台
  • 龙岩网站设计招聘网宁波seo关键词优化制作
  • 自己做网站的各种代码朝阳区seo搜索引擎优化怎么样
  • 比较容易做的网站跨境电商有哪些平台
  • 自己做照片书的网站seo基础培训教程
  • 石家庄大型网站设计公司视频营销案例
  • 推广网站wap端怎么做今日热搜新闻头条
  • 怎么用视频做网站登录的背景朋友圈推广文案
  • 双柏县住房和城乡建设局网站适合发软文的平台
  • 公司的帐如何做网站网站关键词优化软件
  • 哪家网站游戏做的比较好最好用的搜索引擎
  • 零食网站建设策划书怎么打广告宣传自己的产品
  • 哈尔滨快速建站服务南昌seo推广公司
  • 福田做商城网站建设找哪家公司好软文网官网
  • 最好茶叶网站建设上海网络营销