您的位置:首页 > 产品设计 > UI/UE

375. Guess Number Higher or Lower II

2017-04-23 17:34 253 查看

一、题目大意

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

我从1到n选择一个数字,你来猜我选择的数字。

每次你猜错,我都会告诉真实值是偏大还是偏小。

然而,当你猜了一个数字x,并且猜错的时候,你必须支付$x给我,当你猜到我选择的数字时,你就可以赢得比赛。

例如:

n=10,我选择了8

第一轮:你猜5,我告诉你真实值大于该值,你支付$5;

第二轮:你猜7,我告诉你真实值大于该值,你支付$7;

第三轮:你猜9,我告诉你真实值小于该值,你支付$9;

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

你最终支付了$5+$7+$9=$21。

给定一个值n≥1,求为了保证赢得比赛,你必须有多少钱。

二、编程思路

2.1、2.2节为不成功的编程思路,关心答案的同学可以直接转到2.3即可。

2.1 初刻拍案惊奇

乍一看此题可以使用二分法求解。

n=1,{1},ans=0;

n=2,{1,2},ans=1;

n=3,{1,2,3},ans=2;

n=4,{1,2,3,4},ans=min{2+3,3+1}=4;



似乎没问题,令f(x,y)表示猜[x,y]范围内所需要花的钱,med=x+y2,若med为整数,则先猜med;若med不是整数,则猜medf=floor(med)与medc=ceil(med)两种情况,取其中情况较小的。

总结其递推公式如下:

f(x,y)=0;

f(x,y)=x, y=x+1;

f(x,y)=med+f(x,med−1)+f(med+1,y), medc==medf

f(x,y)=min{medc+f(x,medc−1)+f(medc+1,y),medf+f(x,medf−1)+f(medf+1,y)}, medc!=medf

但是当n==5时,根据二分法求出来的是:n=5,{1,2,3,4,5},f(1,5)=3+4=7,而正确的结果应该是f(1,5)=2+4=6。

二分法宣告失败,这是因为二分法只能够找到猜的次数最少的,而不能够保证所猜的数字和最小。

2.2 二刻拍案惊奇

既然二分法不行,那就使用动态规划思路进行求解,继续找规律。

n=1,{1},ans=0;

n=2,{1,2},ans=min{1,2}=1;

n=3,{1,2,3},ans=min{1+2,2,3+1};枚举第一次分别猜1 2 3的情况。

n=4,{1,2,3,4},ans=min{1+{2,3,4}, 2+{3,4}+{1},3+{1,2}+{4}, 4+{1,2,3}}=4;



n,{1,2,3,…,n},ans=MINi=ni=1{i+max({1,2,3,…,i−1}, {i+1,…,n}},即分别枚举猜1…n的情况,从而将问题分解为左右两个子序列的问题。即上式中的{1,2,3,…,i−1}与{i+1,…,n},然后分别求其需要的钱数即可。

至此,思路还没有出现问题。

经过初步观察似乎可以发现,右边序列需要的钱数{i+1,…,n}?=(似乎等于)i+{1,…,n−i}于是总结出如下递推公式:

令dp[i]表示数字范围为1…i之间时,为了保证猜中数字所需要的最少钱数,则

dp[0]=0;

dp[1]=0;

dp[2]=1;

dp[i]=MINk=ik=1(k+max{dp[k−1],dp[i−j]+((i−j)<2?0:j)})

2.3 三刻拍案惊奇

以上思路中,右边序列需要的钱数{i+1,…,n}?=(似乎等于)i+{1,…,n−i}属于根据直觉得出,与正确结果对比发现,当n≥12时,会出现错误。其实只有当子序列中只猜一次时,以上关系才成立。

继续使用动态规划思路,令dp[i][j]猜中[i,j]范围之内数字时所需要最少钱数。则递推公式很容易获得,

dp[i][j]=MINk=jk=i{k+max{dp[i][k−1],dp[k+1][j]}}

三、代码设计

class Solution {
public:
int getMoneyAmount(int n) {
if(n ==0) return 0;
vector<vector<int> > dp(n+1, vector<int>(n+1, 0));
//注意此处的迭代方向
for(int i = n-1; i > 0; i--)
{
for(int j = i+1; j <=n; j++)
{
int ans = 0xfffffff;
for(int k = i; k <j; k++)
ans = min(ans, k + max(dp[i][k-1], dp[k+1][j]));
dp[i][j] = ans;
}
}
return dp[1]
;
}
};


参考博客

LeetCode题解

[LeetCode]Guess Number Higher or Lower II
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息