leetcode 464 我能贏嗎?

2021-10-09 01:27:04 字數 2098 閱讀 9019

在 「100 game」 這個遊戲中,兩名玩家輪流選擇從 1 到 10 的任意整數,累計整數和,先使得累計整數和達到 100 的玩家,即為勝者。

如果我們將遊戲規則改為 「玩家不能重複使用整數」 呢?

例如,兩個玩家可以輪流從公共整數池中抽取從 1 到 15 的整數(不放回),直到累計整數和 >= 100。

給定乙個整數 maxchoosableinteger (整數池中可選擇的最大數)和另乙個整數 desiredtotal(累計和),判斷先出手的玩家是否能穩贏(假設兩位玩家遊戲時都表現最佳)?

你可以假設 maxchoosableinteger 不會大於 20, desiredtotal 不會大於 300

示例

輸入:

maxchoosableinteger = 10

desiredtotal = 11

輸出:false

解釋:無論第乙個玩家選擇哪個整數,他都會失敗。

第乙個玩家可以選擇從 1 到 10 的整數。

如果第乙個玩家選擇 1,那麼第二個玩家只能選擇從 2 到 10 的整數。

第二個玩家可以通過選擇整數 10(那麼累積和為 11 >= desiredtotal),從而取得勝利.

同樣地,第乙個玩家選擇任意其他整數,第二個玩家都會贏。

輸入maxchoosableinteger = 10

desiredtotal = 5

輸出true

解釋:只要第乙個玩家選擇 >= 5的數,都可以穩贏

輸入:maxchoosableinteger = 5

desiredtotal = 100

輸出:false

解釋:無論兩個玩家怎麼選擇,都不可能達到100,因此都算輸

穩贏的意思只要存在乙個數,當我選擇這個數,無論對方怎麼選擇,我都穩贏。

穩輸的意思是,窮盡所有選擇,都無法找出乙個數能讓自己穩贏。

當maxchoosableinteger >= desiredtotal 時,第乙個人先選擇,那麼一定穩贏,

當所有數字的累計和 < desiredtotal時,第乙個人無論怎麼選,兩個人都是輸,因為不可能達到

根據定義,如果第乙個人要穩贏,那麼只要在選擇了乙個數之後,對方穩輸就可以了,所以這是乙個遞迴問題,不過我們需要記錄哪些數字被選擇了,這裡採用了乙個小技巧,使用位運算來儲存當前哪些數字被選擇

如果maxchoosableinteger = 1, 那麼當1被選擇,我們用1表示,未被選擇用0表示

如果maxchoosableinteger =2, 如果都未選擇用00表示,如果1被選擇用01表示,2被選擇用10表示,如果都被選擇,則用11表示。

因此 選擇第i個數,可以用state | 1 << i-1來表示,而判斷第i個數是否被選擇,可以用 (state & 1 << i-1) == 0來判斷,等於0則未被選擇,不等於0則已經被選擇過了。

定義dp陣列,用來儲存在狀態state下,是否能夠穩贏,因為遞迴會有很多重複計算產生,所以通過dp陣列消除重複計算。

下面上**:

class solution 

if((maxchoosableinteger+1)*maxchoosableinteger/2 < desiredtotal)

return helper(maxchoosableinteger,desiredtotal,new boolean[(1 << maxchoosableinteger)], 0);

}private boolean helper(int maxchoosableinteger, int desiredtotal, boolean dp, int state)

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

// 當前的值大於等於目標值的時候,說明穩贏

// 或者 當選擇了當前值, 對方穩輸的話,自己也是穩贏。

int curstate = (1 << i-1) | state;

if(i >= desiredtotal || !helper(maxchoosableinteger, desiredtotal-i, dp, curstate))

}return dp[state] = false;

}}

leetcode 464 我能贏嗎

題目 在 100 game 這個遊戲中,兩名玩家輪流選擇從 1 到 10 的任意整數,累計整數和,先使得累計整數和達到 100 的玩家,即為勝者。如果我們將遊戲規則改為 玩家不能重複使用整數 呢?例如,兩個玩家可以輪流從公共整數池中抽取從 1 到 15 的整數 不放回 直到累計整數和 100。給定乙...

leetcode 464 我能贏嗎

參考思路是遍歷每一種可能性,得出必勝的走法。然而,用遞迴會存在很多的重複計算,所以可用動態規劃儲存下計算的狀態,用map儲存,其中int對應current,考慮 所以可以用int來儲存1 20的數字是否使用,比如1,就相當於1 current 即將第一位 置1 以此類推。首先判斷,如果maxchoo...

464 我能贏嗎

在 100 game 這個遊戲中,兩名玩家輪流選擇從 1 到 10 的任意整數,累計整數和,先使得累計整數和達到 100 的玩家,即為勝者。如果我們將遊戲規則改為 玩家不能重複使用整數 呢?例如,兩個玩家可以輪流從公共整數池中抽取從 1 到 15 的整數 不放回 直到累計整數和 100。給定乙個整數...