@stupidbird911 said in [How does one think up DP solutions for these types of problems?](/post/122697):
> Practice on similar questions, think carefully and you would get better understanding. Almost no one could solve it the first day he/she learns DP.
>
> For this problem, if you have enough experience, it's natural to come up with the O(n3) dp solution. When I first approached it, here is what I thought:
>
> In the first round, I could choose any number between 1 and n. The goal is minimize the money I would pay and naturally there is one or more numbers corresponding to the optimal strategy.
>
> At this point, usually either there is some formula or rule that could guide you to which number OR you should try every number and compute the cost for each choice. The former case often corresponds to brain teasers or math knowledge or insights so it's not as usual as the second case (we are programers rather than mathematicians ).
>
> Suppose I choose number k, now I should pay k, then the correct number is (1) == k, (2) > k (3) < k. Now that the problem is asking for the case of a guaranteed win, so we should consider the worst case, which is the worse one of (2) and (3).
>
> If (2), we then want to know how much at least we should pay to win of guessing a number between 1 to k-1. If (3) then we want to know how much at least for guessing between k+1 and n. At this point, a sub-problem is clear. I.e. how much at least we should pay to win of guessing a number between [i, j]. It's also clear that sol(i, j) by choose k = k + max(sol(i, k-1), (k+1, j)) k from i to j.
>
> DP has yet come in until we easily realize we would do a lot of repeated computations for sol(i, j).
>
> Going back to the choice step. For each choice of k, we could compute the cost, and we choose the minimum cost. So finally we get sol(i, j) = min_k (k + max(sol(i, k-1), (k+1, j)) k from i to j.
>
> The rest details (base case, directions) are easier once you figure out the above part and have practiced enough about DP.
>
> As you can see, it may look daunting for beginners but it's natural for the experienced. Practice more and I guarantee you could solve these questions soon on your own. (try flip game II, burst balloon, max coins on a line(not leetcode))
/**
* common dp top to bottom method:
* write codes that use recursive method first
* based on the recursive version, check dp table berfore recursion,
* save result into dp table after recursion
*/
public class Solution {
public int getMoneyAmountDP(int[][] dp, int s, int e) {
if (s >= e) return 0;
// check if dp[s][e] has been calculated if so just return
if (dp[s][e] != 0) return dp[s][e];
int min = Integer.MAX_VALUE;
for (int i=s; i<=e; i++)
min = Math.min(min, i + Math.max(getMoneyAmountDP(dp, s, i-1), getMoneyAmountDP(dp, i+1, e)));
// save intermediate results for later useage
dp[s][e] = min;
return min;
}
public int getMoneyAmount(int n) {
int[][] dp = new int[n+1][n+1];
getMoneyAmountDP(dp, 1, n);
return dp[1][n];
}
}