375. Guess Number Higher or Lower II
2016-12-22 02:30
316 查看
最后更新
四刷?
极大极小算法。。还是叫极小极大的。。
首先要看怎么能保证赢。
比如2个数,猜第一个猜第二个都能保证下一轮我们赢定了,为了少交钱,我们猜小的。
比如3个数,猜第二个才能保证下一轮再猜一定能赢。
比如4个数,怎么猜都不能保证下一轮一定赢,所以要猜两轮。第一轮猜1,2,3还是4就很讲究了。
猜1就是num1 + dp[2][4](今后花费)
猜2就是dp[1][1](今后花费) + num2或者num[1] + dp[3][4](今后花费)
...
4种里每种都算出来,看哪种花费最少,选最少的。
而现在有N种。。。
也是个game theory,我们2次决定中夹杂着对方的决定,对方的决定是对我们最不利的。
所谓最不利,就是我们选一个数之后,答案比我们的数大还是小是由对方决定的,他会看看答案比我们大他赚钱多还是答案比我们小他赚钱多,然后选个他赚钱多的。
所以选完数之后,我们的花费是当前选择的数,加上答案大的花费和答案小的花费里大的那个。
而我们的选择是,选哪个数花费最小。
所以就是在每个最大值里选个最小的。
一刷
这个题操了。
首先弄懂这个题要求什么就花了好久。
是这个意思……
给1到N的数,让你猜,不管你猜几,猜错了给你猜的数的钱。 猜8,错了,付8元。
然后问你有多少钱才能保证一定能找到答案。
其实可以理解为,不管答案是几,用你现有的钱,总能找到答案。
举个例子,假如有1到10让我猜,现在我有一个亿,我肯定能猜出来。但是问题是我没那么多钱,至少有几块钱能保证我猜出来。
这个题有一个假设,就是假设我不是傻逼。
比如1-10 我猜7,小了,那么结果是8 9 10中一个。接下来我肯定猜9,因为如果没猜中,比9小的话答案就是8,否则是10.
其实这个题,不用在乎答案是几,目的是要一个猜法,按这个猜法,一定能找到答案。
比如刚才的例子,1-10,7+9=16是我们需要的资本,16元保证不管1-10里哪个数是答案,我们都能猜到,最多花16元。
那么7+9是怎么来的?
首先看9
在猜了7之后,有2种可能,一种是答案比7小,一种是答案比7大。
所以答案要么出自1-6 要么出自 8- 10
为了 ==保证== 一定能猜到,我们必须假设出自大的一边。
此时的花费就是当前的7+max(1-6,8-10)
那第一次的7是怎么来的,为什么第一次猜7?
没什么好办法,只能遍历,从1-10 假如猜1会如何,猜2会如何,遍历一次,找到==最小==的起始点,这里又是最小了。
其实我这种孤陋寡闻的弱智是第一次听说MiniMax这个概念,不是很理解,这个题想了好久才明白。
看代码。。
dp[L][R]是从L到R至少要几个钱
helper(L,R,dp)是计算L到R至少需要多少钱,存在DP[L][R],并RETURN这个值
具体怎么算的,遍历从L到R,然后取最小的,就是至少多少钱 就是一开始解释的1-10都来一遍。
里面有很多重复计算,所以 如果DP[L][R]已经被计算过一次,直接返还就行
另外注意的就是,DP[N+1][N+1] 不是 DP
遍历1到N的时候 还需要用到0…… 猜0不用赔钱,所以猜一下无妨。。
不好解释,希望二刷能解释清楚。
二刷依然很迷茫。有了极小极大的思路,但是想到用二维DP数组来表示区间运算结果来去掉重复计算。
对于M,为了保证一定能猜中,要选最大值,从0~(M-1), (M+1)~N 里面选,然后加上自己。
至于M怎么来的,遍历来的。。。。。。。。这个也没想到就是遍历。。
剩下的都比较好理解。
```Java
public class Solution {
public int getMoneyAmount(int n)
{
int[][] dp = new int[n+1][n+1];
}
```
这种题对于富逼来说没意义,钱比33位表示的最大值多,就一定能保证赢,不需要用任何算法。。。
三刷
极大极小值算法。
dp[i][j]表示从i-j保证猜中的最小值。
四刷?
极大极小算法。。还是叫极小极大的。。
首先要看怎么能保证赢。
比如2个数,猜第一个猜第二个都能保证下一轮我们赢定了,为了少交钱,我们猜小的。
比如3个数,猜第二个才能保证下一轮再猜一定能赢。
比如4个数,怎么猜都不能保证下一轮一定赢,所以要猜两轮。第一轮猜1,2,3还是4就很讲究了。
猜1就是num1 + dp[2][4](今后花费)
猜2就是dp[1][1](今后花费) + num2或者num[1] + dp[3][4](今后花费)
...
4种里每种都算出来,看哪种花费最少,选最少的。
而现在有N种。。。
也是个game theory,我们2次决定中夹杂着对方的决定,对方的决定是对我们最不利的。
所谓最不利,就是我们选一个数之后,答案比我们的数大还是小是由对方决定的,他会看看答案比我们大他赚钱多还是答案比我们小他赚钱多,然后选个他赚钱多的。
所以选完数之后,我们的花费是当前选择的数,加上答案大的花费和答案小的花费里大的那个。
而我们的选择是,选哪个数花费最小。
所以就是在每个最大值里选个最小的。
public class Solution { public int getMoneyAmount(int n) { if (n <= 1) return 0; int[][] dp = new int[n+1][n+1]; for (int[] num : dp) { Arrays.fill(num, -1); } dp[1] = guess(1, n, dp); return dp[1] ; } public int guess(int start, int end, int[][] dp) { if (start > end) return 0; if (end == start) return 0; if (end - start == 1) return start; if (dp[start][end] != -1) return dp[start][end]; int res = Integer.MAX_VALUE; for (int i = start; i <= end; i++) { int left = guess(start, i-1, dp); int right = guess(i+1, end, dp); int makeSure = Math.max(left, right); res = Math.min(res, makeSure + i); } dp[start][end] = res; return res; } }
一刷
这个题操了。
首先弄懂这个题要求什么就花了好久。
是这个意思……
给1到N的数,让你猜,不管你猜几,猜错了给你猜的数的钱。 猜8,错了,付8元。
然后问你有多少钱才能保证一定能找到答案。
其实可以理解为,不管答案是几,用你现有的钱,总能找到答案。
举个例子,假如有1到10让我猜,现在我有一个亿,我肯定能猜出来。但是问题是我没那么多钱,至少有几块钱能保证我猜出来。
这个题有一个假设,就是假设我不是傻逼。
比如1-10 我猜7,小了,那么结果是8 9 10中一个。接下来我肯定猜9,因为如果没猜中,比9小的话答案就是8,否则是10.
其实这个题,不用在乎答案是几,目的是要一个猜法,按这个猜法,一定能找到答案。
比如刚才的例子,1-10,7+9=16是我们需要的资本,16元保证不管1-10里哪个数是答案,我们都能猜到,最多花16元。
那么7+9是怎么来的?
首先看9
在猜了7之后,有2种可能,一种是答案比7小,一种是答案比7大。
所以答案要么出自1-6 要么出自 8- 10
为了 ==保证== 一定能猜到,我们必须假设出自大的一边。
此时的花费就是当前的7+max(1-6,8-10)
那第一次的7是怎么来的,为什么第一次猜7?
没什么好办法,只能遍历,从1-10 假如猜1会如何,猜2会如何,遍历一次,找到==最小==的起始点,这里又是最小了。
其实我这种孤陋寡闻的弱智是第一次听说MiniMax这个概念,不是很理解,这个题想了好久才明白。
看代码。。
public class Solution { public int getMoneyAmount(int n) { int[][] dp = new int[n+1][n+1]; return helper(1,n,dp); } public int helper(int left, int right, int[][] dp) { if(left < right) { if(dp[left][right] != 0) return dp[left][right]; //we already calculated it once, just return. int temp = Integer.MAX_VALUE; for(int n = left; n <= right; n++) { temp = Math.min(temp,n+Math.max(helper(left,n-1,dp),helper(n+1,right,dp))); } dp[left][right] = temp; return temp; } else { return 0; //not return left, becuase I guess the right one //thus we dont need to pay for this guess } } }
dp[L][R]是从L到R至少要几个钱
helper(L,R,dp)是计算L到R至少需要多少钱,存在DP[L][R],并RETURN这个值
具体怎么算的,遍历从L到R,然后取最小的,就是至少多少钱 就是一开始解释的1-10都来一遍。
里面有很多重复计算,所以 如果DP[L][R]已经被计算过一次,直接返还就行
另外注意的就是,DP[N+1][N+1] 不是 DP
遍历1到N的时候 还需要用到0…… 猜0不用赔钱,所以猜一下无妨。。
不好解释,希望二刷能解释清楚。
------
二刷。二刷依然很迷茫。有了极小极大的思路,但是想到用二维DP数组来表示区间运算结果来去掉重复计算。
对于M,为了保证一定能猜中,要选最大值,从0~(M-1), (M+1)~N 里面选,然后加上自己。
至于M怎么来的,遍历来的。。。。。。。。这个也没想到就是遍历。。
剩下的都比较好理解。
```Java
public class Solution {
public int getMoneyAmount(int n)
{
int[][] dp = new int[n+1][n+1];
return helper(dp,1,n); } public int helper(int[][] dp, int from, int to) { if(from>=to) return 0; else { if(dp[from][to]!=0) return dp[from][to]; int min = Integer.MAX_VALUE; for(int i = from; i <= to; i++) { min = Math.min(min,Math.max(helper(dp,from,i-1),helper(dp,i+1,to)) + i); } dp[from][to] = min; return min; } }
}
```
这种题对于富逼来说没意义,钱比33位表示的最大值多,就一定能保证赢,不需要用任何算法。。。
三刷
极大极小值算法。
dp[i][j]表示从i-j保证猜中的最小值。
public class Solution { public int getMoneyAmount(int n) { if (n == 1) return 0; int[][] dp = new int[n+1][n+1]; return helper(1, n, dp); } public int helper(int l, int r, int[][] dp) { if (l >= r) return 0; if (dp[l][r] != 0) return dp[l][r]; int min = Integer.MAX_VALUE; for (int i = l; i <= r; i++) { int leftCost = helper(l, i-1, dp) + i; int rightCost = helper(i+1, r, dp) + i; int guarantee = Math.max(leftCost, rightCost); min = Math.min(min, guarantee); } dp[l][r] = min; return dp[l][r]; } }
相关文章推荐
- 375. Guess Number Higher or Lower II
- [LeetCode]--375.Guess Number Higher or Lower II
- [Leetcode 375] Guess Number Higher or Lower II
- 375. Guess Number Higher or Lower II
- LeetCode 题解(Week 12):375. Guess Number Higher or Lower II
- 374,375. Guess Number Higher or Lower I,II
- LeetCode 375. Guess Number Higher or Lower II
- [leetcode-375]Guess Number Higher or Lower II(java)
- LeetCode | 375. Guess Number Higher or Lower II 树状DP
- LeetCode - 375 - Guess Number Higher or Lower II
- 375. Guess Number Higher or Lower II
- Leetcode:375. Guess Number Higher or Lower II
- leetcode 375. Guess Number Higher or Lower II 猜数游戏+动态规划DP+最大最小化问题
- 375. Guess Number Higher or Lower II
- 375. Guess Number Higher or Lower II
- Leetcode 375. Guess Number Higher or Lower II
- leetcode 375. Guess Number Higher or Lower II
- [leetcode] 375. Guess Number Higher or Lower II 解题报告
- 375. Guess Number Higher or Lower II
- LeetCode 375. Guess Number Higher or Lower II