We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I'll tell you whether the number I picked is higher or lower.
However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.
Example:
n = 10, I pick 8. First round: You guess 5, I tell you that it's higher. You pay $5. Second round: You guess 7, I tell you that it's higher. You pay $7. Third round: You guess 9, I tell you that it's lower. You pay $9. Game over. 8 is the number I picked. You end up paying $5 + $7 + $9 = $21.
Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.
自下而上的动态规划或者自上而下的记忆化dfs:
动态规划:
public class Solution2 {
public int getMoneyAmount(int n) {
int[][] dp=new int[n+2][n+2];//这个小细节注意一下 因为Math.max(dp[i][k-1], dp[k+1][j])+k 所以两边都要留出默认值为0的空白边界
for(int len=0;len<n;len++){
for(int i=1;i<=n-len;i++){
int j=i+len;
if(i==j) dp[i][j]=0;
else{
dp[i][j]=Integer.MAX_VALUE;
for(int k=i;k<=j;k++){
dp[i][j]=Math.min(dp[i][j],Math.max(dp[i][k-1], dp[k+1][j])+k);
}
}
}
}
return dp[1][n];
}
}
记忆化dfs:
public class Solution {
public int getMoneyAmount(int n) {
dp=new int[n+1][n+1];
for(int i=0;i<dp.length;i++){
Arrays.fill(dp[i],Integer.MAX_VALUE);
}
return dfs(1,n);
}
int[][] dp;
public int dfs(int l,int r){
if(l>=r) return 0;
if(dp[l][r]!=Integer.MAX_VALUE) return dp[l][r];
for(int i=l;i<=r;i++){
dp[l][r]=Math.min(dp[l][r], Math.max(i+dfs(l,i-1),i+dfs(i+1,r)));
}
return dp[l][r];
}
}