375. Guess Number Higher or Lower II
今天的题目是375. Guess Number Higher or Lower II。
一道动态规划问题,一开始以为是通过二分查找的方式来计算就好了,但是后面发现这样算出来答案不是最优的。
思路大概是这样的,把问题先泛化为,给定从i
到j
的数字,猜数字的最大代价,为了得到最大代价,我们不妨假设每次都猜错,直到只有一个元素时。
第一次猜的时候,我们可以猜从i
到j
的任意一个数字k
,这时代价为k
,猜错后可能得到两种回答,比k
大或者比k
小,这时我们的问题转换为两个子问题:
- 给定
i
到k-1
的数字,猜数字的最大代价 - 给定
k+1
到j
的数字,猜数字的最大代价
当i
到j
的数字的数目小于等于1时,代价为0
。
据此,我们可以写出以下动态规划方程:
$$
dp[i,j] = \left{
\begin{aligned}
0 & , & (j - i + 1) >= 0 \
min_{i<=k<=j}{dp[i,k-1] + k + dp[k+1,j]} & , & others
\end{aligned}
\right.
$$
由于计算dp[i,j]
需要dp[i,k-1]
和dp[k+1,j]
,所以我们可以直到它是沿着斜对角线计算得到dp[1,n]
的,如下图所示:
因此,我们可以根据动态规划方程写出如下代码:
1 | int getMoneyAmount(int n) { |