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:
1 n = 10, I pick 8.
2
3 First round: You guess 5, I tell you that it's higher. You pay $5.
4 Second round: You guess 7, I tell you that it's higher. You pay $7.
5 Third round: You guess 9, I tell you that it's lower. You pay $9.
6
7 Game over. 8 is the number I picked.
8
9 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.
思路:DP。
设OPT(i, j)表示i到j范围内的最优解。假设我们猜的数字是k,则i <= k <= j。之后,k将该问题分解为两个子问题,OPT(i, k-1)和OPT(k+1, j)。我们要的是其中的最坏情况。因此OPT(i, j) = min(k + max(OPT(i, k-1), OPT(k+1, j)))
复杂度为O(n^3).
1 class Solution { 2 public: 3 int getMoneyAmount(int n) { 4 vector<vector<int> > dp(n + 1, vector<int>(n + 1, 0)); 5 for (int st = n; st > 0; st--) { 6 for (int ed = st + 1; ed <= n; ed++) { 7 int localMin = INT_MAX; 8 for (int k = st; k <= ed; k++) { 9 int cur = k + std::max(k == st ? 0 : dp[st][k-1], k == ed ? 0 : dp[k+1][ed]); 10 localMin = std::min(cur, localMin); 11 } 12 dp[st][ed] = localMin; 13 } 14 } 15 return dp[1][n]; 16 } 17 };