这类题目思想是两层极值问题。比如要求求出一个极大值,而这个极大值的选择是在众多的极小值中选择的。
1、375. Guess Number Higher or Lower II
在1~n中给定一个数,要求猜测这个数是多少,最后猜出这个数的代价是之前猜的数的和。
在374类似问题中,是求解最少的猜测次数,使用二分法的思想。这个题目如果受这种思想的限制,就想不到一个合适的解法。
回归到最一般的思维路线:
第一次猜测时,如果猜测i,那么下一次猜测一定在1~i-1和i+1~n之间。假设我们已经知道了这两个区间的猜测代价:f[1][i-1]和f[i+1][n],那么选择这两个的最大的一个,因为题目的要求的猜测是满足所有情况的最小猜测代价,即考虑最差情况下的最好选择。
最好选择体现在i的选择上:第一次的i的选择是任意的,在所有的选择中找到最小的那个代价就是结果。
写出递归函数:
class Solution {
public:
int getMoneyAmount(int n) {
return getMoney(0,n);
}
int getMoney(int i,int j){
if(i==j) return 0;
if(i>j) return 0;
int res=numeric_limits<int>::max();
int temp=0;
for(int k=i;k<=j;k++)
{
temp=k+max(getMoney(i,k-1),getMoney(k+1,j));
res=min(res,temp);
}
return res;
}
};
在此基础上改写动态规划:
class Solution {
public:
int getMoneyAmount(int n) {
vector<vector<int>> dp(n+1,vector<int>(n+1,0));
for(int i=n;i>=1;i--)
{
for(int j=i;j<=n;j++)
{
if(i==j)
{
dp[i][j]=0;
continue;
}
dp[i][j]=numeric_limits<int>::max();
int temp=0;
for(int k=i;k<=j;k++)
{
temp=k+max(dp[i][k-1],k+1>n?0:dp[k+1][j]);
dp[i][j]=min(dp[i][j],temp);
}
}
}
return dp[1][n];
}
};
2、486 predict the winner 纸牌博弈问题
参考连接[置顶] 动态规划/leetcode/直接推导递推公式
3、分金子(360公司2017春招真题) 纸牌博弈问题 程序员代码面试指南 与第二题是同一题
4、464. Can I Win
In the "100 game," two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins.
What if we change the game so that players cannot re-use integers?
For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100.
Given an integer maxChoosableInteger
and another integer desiredTotal
, determine if the first player to move can force a win, assuming both players play optimally.
You can always assume that maxChoosableInteger
will not be larger than 20 and desiredTotal
will not be larger than 300.
Example
Input: maxChoosableInteger = 10 desiredTotal = 11 Output: false Explanation: No matter which integer the first player choose, the first player will lose. The first player can choose an integer from 1 up to 10. If the first player choose 1, the second player can only choose integers from 2 up to 10. The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal. Same with other integers chosen by the first player, the second player will always win
给定一个范围的集合,两个人抽数累加,当累加到给定值的时候的那个玩家算赢,判断第一个玩家是否会赢?