375. Guess Number Higher or Lower 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.

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.

 此题开始的时候并不会做,看了标签才知道需要使用动态规划的方法解决。动态规划的思想是,如果原问题可以分解成若干规模较小的子问题。它的一个特点是最优子结构特点,即原问题的解是由子问题的最优解组成。那么此题为什么不能用普通的递归方法来解决呢?因为子问题之间不是相互独立的。子问题之间要进行比较,找出相对来说较大的pay。这道题为什么不能像之前的Guess Number Higher or Lower那种只使用二分查找来做呢?二分查找找的是某一个值,或者给出一个target,造出最接近target值时候使用二分查找比较方便,而此题是找出过程。此题的难点在于状态方程比较难想。想法是,要求这一范围内的最小pay,就是将这一范围分成三个部分,第一个是划分点,第二是划分点的左面,第三是划分点的右面。为了避免重叠子问题,保存的是最小的pay值,代码如下:

 1 public class Solution {
 2     public int getMoneyAmount(int n) {
 3         int[][] table = new int[n+1][n+1];
 4         return DP(table,1,n);
 5     }
 6     public int DP(int[][] table,int s,int e){
 7         if(s>=e) return 0;
 8         if(table[s][e]!=0) return table[s][e];
 9         int res = Integer.MAX_VALUE;
10         for(int i=s;i<=e;i++){
11             table[s][e] = i+Math.max(DP(table,s,i-1),DP(table,i+1,e));
12             res = Math.min(res,table[s][e]);
13         }
14         table[s][e] = res;
15         return res;
16     }
17 }

 

posted @ 2017-03-01 01:26  CodesKiller  阅读(170)  评论(0编辑  收藏  举报