LintCode刷题——Guess Number Game II
题目内容:
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.
样例:
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.
So when n = `10, return
16`
算法分析:
本题大意就是给定任意一个数n, 任意给定数字i,1< i < n:
①如果玩家猜对数字i,则游戏结束;
②否则,玩家支付相应的金额 i,然后庄家告诉玩家这个数是大了还是小了,然后玩家继续猜。
本题留给我们的问题就是对于任意一个数n,玩家至少需要准备多少钱才能够保证其能够取胜。但是对于本题,我们并不知道庄家到底在1到n中挑了哪一个数,每个数均有可能成为庄家所挑选的那个数,因此我们需要对所有的挑选情况进行遍历,得出所有情况的开销,从而找到总开销最小的那种情况。那么怎么进行遍历呢?以下为主要的算法思路:
首先我们要明确的一点就是为了带的钱确保一定能赢,所以我们假设自己的运气真的是差到家了,每次我们猜的都是猜到最后一个数我们才猜对,之前一直在付钱,因此:
①对于一个区间[1,n],假设我们猜 i 且没有猜对,因此我们支付金额 i 后庄家告诉我们是大了还是小了,因此眼下我们猜测的区间就缩减为[1,i-1]或者[i+1,n];
②无论是哪个区间,在[1,i-1]和[i+1,n]这两个区间猜数字最终都会得到一个金钱的开销,假设这两个开销已经是各自区间的最大值,因此为了确保赢,我们还是必须要考虑最差情况并选择两者中的较大者;
③通过①和②的分析,我们可以建立一个数组DP[i][j],i<j,其表示区间[i,j]中猜测数字时所需的最大金钱开销,因此得出动态规划表达式为DP[i][j] = min{max{DP[i][k],DP[k][j]}+k},其中 i=<k<=j;min表示所有最大开销情况中的最小值;
代码:
public class Solution { /* * @param n: An integer * @return: how much money you need to have to guarantee a win */ int[][] DP; public int findSolution(int begin, int end){ if(begin>=end){ return 0; } if(DP[begin][end]!=0){ return DP[begin][end]; } DP[begin][end]=Integer.MAX_VALUE; for(int i=begin;i<=end;i++){ int left = findSolution(begin,i-1); int right = findSolution(i+1,end); int temp = Math.max(left,right) + i; DP[begin][end] = Math.min(temp,DP[begin][end]); } return DP[begin][end]; } public int getMoneyAmount(int n) { // write your code here DP = new int[n+1][n+1]; int result = findSolution(1,n); return result; } }
其中DP即为动态规划中的记忆部分,大大降低了动态规划中不必要的时间开销;