LeetCode 375 猜數字大小 II

2021-10-24 01:55:27 字數 3060 閱讀 6049

我們正在玩乙個猜數遊戲,遊戲規則如下:

我從 1 到 n 之間選擇乙個數字,你來猜我選了哪個數字。

每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。

然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。

示例:n = 10, 我選擇了8.

第一輪: 你猜我選擇的數字是5,我會告訴你,我的數字更大一些,然後你需要支付5塊。

第二輪: 你猜是7,我告訴你,我的數字更大一些,你支付7塊。

第三輪: 你猜是9,我告訴你,我的數字更小一些,你支付9塊。

遊戲結束。8 就是我選的數字。

你最終要支付 5 + 7 + 9 = 21 塊錢。

給定 n ≥ 1,計算你至少需要擁有多少現金才能確保你能贏得這個遊戲。

乍一眼看上去,很像二分的查詢方法,但是二分卻不能保證就一定是最小的那個方案。所以我們採用窮舉法(遞迴法)來分析。

首先,可以明確這個問題和區間是有關的,直接定義,狀態函式dp[

i][j

]dp[i][j]

dp[i][

j]區間[ i,

j]

[i,j]

[i,j

]之間消耗的確保獲勝最小現金。

要求得這個現金,我們需要按照最壞情況考慮,就是我們下一次猜測是錯誤的情況下,需要的資金,把所有猜測錯誤的情況列舉出來可以有

m ax

(dp[

i][k

−1],

dp[k

+1][

j])+

kk∈[

i+1,

j−1]

\begin max(dp[i][k-1], dp[k+1][j]) + k & & k\in[i+1,j-1] \end

max(dp

[i][

k−1]

,dp[

k+1]

[j])

+k​​

k∈[i

+1,j

−1]​

這裡用max是因為給出提示後,只會選擇任一邊,為了保險起見,就選擇最大的部分。

在這些猜錯的最壞情況下,我們找到乙個最小現金,意味著我們在面對這個未知區間時,要盲猜乙個效率最高的數,這個數在列舉的k之中,這裡用min找到最小值。

d p[

i][j

]=

min⁡k(

max(

dp[i

][k−

1],d

p[k+

1][j

])+k

)k∈[

i+1,

j−1]

\begin dp[i][j] =\min_k(max(dp[i][k-1], dp[k+1][j]) + k) & & k\in[i+1,j-1] \end

dp[i][

j]=k

min​(m

ax(d

p[i]

[k−1

],dp

[k+1

][j]

)+k)

​​k∈

[i+1

,j−1

]​到這裡我們已經把狀態轉移方程給弄出來。

首先我們可以確定dp[

i][i

]=0,

dp[0

][i]

=0,d

p[n]

[0]=

0dp[i][i]=0,dp[0][i]=0,dp[n][0]=0

dp[i][

i]=0

,dp[

0][i

]=0,

dp[n

][0]

=0,因為當相等的時候不需要猜,涉及0的時候在題目中不需要考慮。那麼剩下的值該如何進行設定?

觀察方程,最終列舉的時候取得是最小值,可以把dp[

i][j

]dp[i][j]

dp[i][

j]的初始值設定為正無窮。

首先可以確定,

i ≤k

−1

1≤

ji\leq k-1 < k+1\leq j

i≤k−

11≤j這裡有個矛盾就是i,j之間的差是可以為1,而k+1與k-1的差為2,這點在迴圈的時候需要注意,即最後k的取值需要把邊界值i,j進行考慮。

其次,回顧轉移方程

d p[

i][j

]=

min⁡k(

max(

dp[i

][k−

1],d

p[k+

1][j

])+k

)k∈[

i+1,

j−1]

\begin dp[i][j] =\min_k(max(dp[i][k-1], dp[k+1][j]) + k) & & k\in[i+1,j-1] \end

dp[i][

j]=k

min​(m

ax(d

p[i]

[k−1

],dp

[k+1

][j]

)+k)

​​k∈

[i+1

,j−1

]​當需要更新的dp[

i][j

]dp[i][j]

dp[i][

j]時,需要用到左後方的dp,所以更新應該是從左到右,從下到上。

class solution 

for(int i=1;i<=n;i++)

}for(int i=0;i<=n;i++)

for(int i=0;i<=n;i++)

for(int i=0;i<=n;i++)

for(int j=2;j<=n;j++)

dp[i][j] = min(dp[i][j], i+dp[i+1][j]);

dp[i][j] = min(dp[i][j], j+dp[i][j-1]);}}

return dp[1][n];

}};```

LeetCode375 猜數字大小 II

我們正在玩乙個猜數遊戲,遊戲規則如下 我從1到n之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第一輪 你...

LeetCode 375 猜數字大小II

我們正在玩乙個猜數遊戲,遊戲規則如下 我從 1 到 n 之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第...

375 猜數字大小 II

我們正在玩乙個猜數遊戲,遊戲規則如下 我從1到n之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第一輪 你...