首页 > 其他 > 详细

375. 猜数字大小 II

时间:2020-02-28 10:44:23      阅读:58      评论:0      收藏:0      [点我收藏+]

 

题目:

链接:https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/

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

我从 1 到 n 之间选择一个数字,你来猜我选了哪个数字。

每次你猜错了,我都会告诉你,我选的数字比你的大了或者小了。

然而,当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x 的现金。直到你猜到我选的数字,你才算赢得了这个游戏。

示例:

n = 10, 我选择了8.

第一轮: 你猜我选择的数字是5,我会告诉你,我的数字更大一些,然后你需要支付5块。
第二轮: 你猜是7,我告诉你,我的数字更大一些,你支付7块。
第三轮: 你猜是9,我告诉你,我的数字更小一些,你支付9块。

游戏结束。8 就是我选的数字。

你最终要支付 5 + 7 + 9 = 21 块钱。
给定 n ≥ 1,计算你至少需要拥有多少现金才能确保你能赢得这个游戏。

解答:

动态规划,但是真的难想。模仿他人题解写的,记录一下吧,反正要是有公司笔试考这题我就直接交卷。。

 1 class Solution {
 2 public:
 3     int getMoneyAmount(int n) {
 4         vector<vector<int>>dp(n+1,vector<int>(n+1,0));
 5         dp[1][1]=0;
 6         int _min;
 7         //对于i到j的数字,如果我们先猜k(i<k<j),得能保证赢得游戏。
 8         //那么需要假设k是错的,取[i,k-1]和[k+1,j]需要更多钱来保证赢的那个,设为bigger
 9         //则第一次猜k的最小需求金额就是k+bigger
10         //对于所有可能的k,都要遍历一遍
11         //最大的那一组k+bigger就是对于i到j的数字序列我们能保证赢得游戏的最小需求金额。
12         
13         //由于dp[i][j]表示给定i到j的序列,我们要赢得游戏所需最少现金
14         //需要从中取i<k<j,即为了求dp[i][j],我们需要知道dp[i][k-1]和dp[k+1][j]。
15         //可以发现要先求行数更大的行以及更小的列,所以选择从下到上,从左到右计算dp数组
16         for(int i=n;i>=1;--i){
17             dp[i][i]=0;
18             for(int j=i+1;j<=n;++j){
19                 _min=INT_MAX;
20                 for(int k=i+1;k<j;++k){
21                     _min=min(_min,k+max(dp[i][k-1],dp[k+1][j]));
22                 }
23                 _min=min(_min,i+dp[i+1][j]);
24                 _min=min(_min,dp[i][j-1]+j);
25                 dp[i][j]=_min;
26             }
27         }
28         return dp[1][n];
29     }
30 };

 

375. 猜数字大小 II

原文:https://www.cnblogs.com/FdWzy/p/12375566.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!