leetcode464:動態(tài)規(guī)劃

在 "100 game" 這個游戲中,兩名玩家輪流選擇從 1 到 10 的任意整數(shù),累計整數(shù)和,先使得累計整數(shù)和達(dá)到 100 的玩家,即為勝者。

如果我們將游戲規(guī)則改為 “玩家不能重復(fù)使用整數(shù)” 呢?

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

給定一個整數(shù) maxChoosableInteger (整數(shù)池中可選擇的最大數(shù))和另一個整數(shù) desiredTotal(累計和),判斷先出手的玩家是否能穩(wěn)贏(假設(shè)兩位玩家游戲時都表現(xiàn)最佳)?

你可以假設(shè) maxChoosableInteger 不會大于 20, desiredTotal 不會大于 300。

示例:

輸入:
       maxChoosableInteger = 10
         desiredTotal = 11
輸出:
     false

解釋:
無論第一個玩家選擇哪個整數(shù),他都會失敗。
第一個玩家可以選擇從 1 到 10 的整數(shù)。
如果第一個玩家選擇 1,那么第二個玩家只能選擇從 2 到 10 的整數(shù)。
第二個玩家可以通過選擇整數(shù) 10(那么累積和為 11 >= desiredTotal),從而取得勝利.
同樣地,第一個玩家選擇任意其他整數(shù),第二個玩家都會贏。

思路

  • 憶化dfs。一開始考慮到A先選,只要有一個選擇的數(shù)返回true就行,B選擇時,需要B之后A的每一次返回true,B才能返回true。這里,B選擇時返回true的含義和A選擇時的true含義是一樣的,true代表A贏。

class Solution {
    public boolean canIWin(int nums, int sum) {
        if(sum==0) return true;
        if((1+nums)*nums/2<sum) return false;
        return dfs(nums,sum,0,new int[1<<20],true);
    }
    boolean dfs(int nums,int sum,int visited,int[] memo,boolean turn){
        if(memo[visited]==1) return true;
        if(memo[visited]==2) return false;
        if(sum<=0){
            if(turn){
                memo[visited]=2;
                return false;
            }
            memo[visited]=1;
            return true;
        }
        for(int i=nums;i>0;i--){
            if(((visited>>(i-1))&1)==1) continue;
            if(turn&&dfs(nums,sum-i,visited|(1<<(i-1)),memo,turn==true?false:true)){//A 一種情況就夠了
                memo[visited]=1;
                return true;
            }
            else if(!turn&&!dfs(nums,sum-i,visited|(1<<(i-1)),memo,turn==true?false:true)){ //B 的每種情況都需要要A贏
                memo[visited]=2;  
                return false;
            }
        }
        if(turn){//A true ,B false
            memo[visited]=2;
        }else{
            memo[visited]=1;
        }
        return !turn;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 7,324評論 0 17
  • 一、Python簡介和環(huán)境搭建以及pip的安裝 4課時實驗課主要內(nèi)容 【Python簡介】: Python 是一個...
    _小老虎_閱讀 6,325評論 0 10
  • 專業(yè)考題類型管理運行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項A選項B選項C選項D選項E選項F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 10,513評論 0 13
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,246評論 0 38
  • 在C語言中,五種基本數(shù)據(jù)類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 4,014評論 0 2

友情鏈接更多精彩內(nèi)容