我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字,你来猜我选了哪个数字。
每次你猜错了,我都会告诉你,我选的数字比你的大了或者小了。 然而,当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x
的现金。直到你猜到我选的数字,你才算赢得了这个游戏。 来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
int getMoneyAmount(int n){
int dp[n+1][n+1];
memset(dp, 0, sizeof(dp));
for(int i = 1; i <n; i++)
{
dp[i][i+1] = i;
}
for(int len = 2; len < n; len++)
{
for(int i = 1; i <= n-len; i++)
{
int min = INT_MAX;
for(int k = i; k < i+len; k++)
{
int res = k + fmax(dp[i][k-1], dp[k+1][i+len]);
min = fmin(min, res);
}
dp[i][i+len] = min;
}
}
return dp[1][n];
}
思路:动态规划
这里题目的意思是选择一个最优的方案,花费最少的钱来解决问题。那么问题来了,需要怎样得到答案,一般首先的思路就是,把所有的方案都尝试一遍,然后比较来得到金额最少的那一个。举例来说,n=5,那么数字可能为1到n,那么就一个一个猜,比如说先猜2,2不对,那么就有2种可能,答案在区间[3,5]或[1,1],假如答案在3和5之间猜一个值,比如说是4,也不对,那就又分成2种可能,在[3,3]或[5,5],那么下一次肯定是对的,那在区间[1,5]中先猜2,需要然后一定能猜中答案的需要花费最多的金额就为2+4 = 6元,那么再计算先猜1,3,4,5这四个数字花费的金额,然后这些金额中花费最少的一定能猜中答案的就是这些金额中的最小值。
如果使用回溯算法计算,那么需要重复计算需要重复计算,那么使用dp数组来记录已经算过的值。那么状态转移方程就为: