在 「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。給定乙個整數...