我們正在玩乙個猜數遊戲,遊戲規則如下:
我從1到n之間選擇乙個數字,你來猜我選了哪個數字。
每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。
然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。
示例:
n = 10, 我選擇了8.
第一輪: 你猜我選擇的數字是5,我會告訴你,我的數字更大一些,然後你需要支付5塊。
第二輪: 你猜是7,我告訴你,我的數字更大一些,你支付7塊。
第三輪: 你猜是9,我告訴你,我的數字更小一些,你支付9塊。
遊戲結束。8 就是我選的數字。
你最終要支付 5 + 7 + 9 = 21 塊錢。
給定n ≥ 1,計算你至少需要擁有多少現金才能確保你能贏得這個遊戲。
思路:這是一道minimax演算法又名極小化極大演算法問題。區域性最大值,全域性最小值。舉例說明:
1、當n = 1
時,顯然cost = 0
2、當n = 2
時,即[1, 2]
,顯然cost=1
3、當n = 3
時,即[1, 2, 3]
,只需要猜中間數字2
就能知道結果,因為比2
大的只有乙個,比2
小的也只有乙個,所以cost=2
4、當n = 4
時,即[1, 2, 3, 4]
。四個數字顯然不能一眼看出最少cost
,那就乙個乙個來計算吧。
5、當n = 5
時,即[1, 2, 3, 4, 5]
,同樣可以挨個計算每個數字,最終得到最小cost
綜上所述,當給定數字n時,可以從1
開始,計算全部至少花費情況,最後取最小花費。
因此有[i,j]區間內的區域性最大值 local_max = k + max(cost(i, k-1), cost(k+1, j)),取最大值的原因是不知道實際數字是比k大,還是比k小,一定要考慮到所有情況,按最壞情況處理。
最後對每一k得到的local_max取最小值,得到[i,j]區間至少需要多少錢贏得遊戲。
注意k是我們可控的,實際數字是我們不可控的。
實際書寫**中,採用記憶陣列dp,dp[i][j]表示[i,j]區間至少需要多少錢贏得遊戲,把已經得到的數儲存下來,減少重複計算。
class solution
dp[s][e]=re;
return re;
}int getmoneyamount(int n)
};
375 猜數字大小 II
我們正在玩乙個猜數遊戲,遊戲規則如下 我從1到n之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第一輪 你...
375 猜數字大小 II
我們正在玩乙個猜數遊戲,遊戲規則如下 我從1到n之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第一輪 你...
375 猜數字大小 II
我們正在玩乙個猜數遊戲,遊戲規則如下 我從 1 到 n 之間選擇乙個數字,你來猜我選了哪個數字。每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。然而,當你猜了數字 x 並且猜錯了的時候,你需要支付金額為 x 的現金。直到你猜到我選的數字,你才算贏得了這個遊戲。示例 n 10,我選擇了8.第...