Guess Number Higher or Lower II 猜数字大小 II

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

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

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

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

示例:

n = 10, 我选择了8.

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

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

你最终要支付 5 + 7 + 9 = 21 块钱。

给定一个 n ≥ 1,计算你至少需要拥有多少现金才能确保你能赢得这个游戏。

思路:这道题我们来看规律。

1:假如n=1或者n=0,那么cost=0

2:假如n=1,2,那么我们猜较小的误差1,根据反馈可以得到正确答案,cost=1

3:假如n=1,2,3,那么猜2,根据反馈也可以得到正确答案,cost=2

到目前为止还没看出来规律,因为前3种是我们的边界条件(第三种其实可以分解为更详细的子问题,不算边界条件,但是不明显,所以暂不分解)

4:假如n=1,2,3,4,由于我们不知道哪种好,所以只能逐个猜:

    猜k=1,对于左边而言,cost=0,对于右边[2,3,4],根据上面的分析,cost=3。综合来看cost=k+max(cost(left)+cost(right))=1+max(0,3)=4

     猜k=2,对于左边1,cost=0,对于右边3,4,cost=3,综合cost=2+max(0,3)=5

     猜k=3,对于左边1,2,cost=1,对于右边4,cost=0,综合cost=3+max(1,0)=4

     猜k=4,对于左边1,2,3,cost=2,对于右边无,cost=0,综合cost=4+max(2,0)=2

取k=1,2,3,4中对应最小的cost总和是4。对于n=1,2,3,4,cost最小是4。

所以我们用memo[i][j]表示[i,j]范围内的最小的cost,用递归得到如下参考代码:

class Solution {
public:
int helpCore(int start,int end, vector<vector<int>>& memo) {
	if (start >= end) {
		return 0;
	}
	if (start == (end - 1)) {
		memo[start][end] = start;
		return memo[start][end];
	}
	if (memo[start][end] > 0) {
		return memo[start][end];
	}
	int res = INT_MAX;
	for (int k = start+1; k < end; k++) {
		int t = k + max(helpCore(start, k - 1, memo), helpCore(k + 1, end, memo));
		res = min(res, t);
	}
	memo[start][end] = res;
	return memo[start][end];
}

int getMoneyAmount(int n) {
	vector<vector<int>> memo(n + 1, vector<int>(n + 1, 0));
	return helpCore(1, n, memo);
}
};




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值