解题思路:这道题目的意思是我告诉你一个n值,然后我会在1到n之间选一个数字,让你来猜我选了哪个数。
我们需要意识到我们在范围 (1, n)中猜数字的时候,需要考虑最坏情况下的代价。也就是说要算每次都猜错的情况下的总体最大开销。
我们首先在 (1, n)中任意挑选一个数字,假设它是个错误的猜测(最坏情况),我们需要用最小代价去猜到需要的数字。那么在一次尝试以后,答案要么在我们猜的数字的左边要么在右边,为了考虑最坏情况,我们需要考虑两者的较大值。因此,如果我们选择 ii 作为第一次尝试,总体最小代价是:
作者:LeetCode
链接:https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/solution/cai-shu-zi-da-xiao-ii-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
—————————————————————————————————
设立二维数组dp[i][j],dp[i][j]表示从i到j的数字之间猜中所需要的最小花费。根据上面的状态转移方程,可以得到C++代码如下:
class Solution {
public:
int getMoneyAmount(int n) {
if(n==1) //1到1之间的最小花费肯定是0
return 0;
if(n==2) //1到2之间的最小花费为1
return 1;
vector<vector<int>> dp(n,vector<int>(n,INT_MAX)); //二维数组用于存储状态转移方程
for(int i=0;i<n-1;i++) //这段程序用于存储当dp[i][i+1]的最小花费,因为二维数组的范围为0到n-1,所以dp[i][i+1]的最小花费不能是i,必须是i+1
{
dp[i][i+1] = i+1;
}
for(int i=0;i<n;i++) //这段程序的作用是初始化dp[i][i]的值为0
{
dp[i][i] = 0;
}
for(int i=n-2;i>=0;i--) //这段程序是考虑在数字i到数字j之间的最小花费
{
for(int j=i+2;j<n;j++)
{
for(int k=i+1;k<j;k++) //循环从i到j之间的所有可能性,找出其中的最小值
{
dp[i][j] = min(dp[i][j],k+1 + max(dp[i][k-1],dp[k+1][j]));
}
}
}
return dp[0][n-1];
}
};