動態規劃 遊戲贏家(一)

2021-08-19 02:02:07 字數 1350 閱讀 1758

給定乙個非負陣列,a、b兩人玩遊戲,輪流從陣列的頭部或者尾部取出元素,加到各自的和中,直到陣列元素取完,取到的元素和最大的玩家贏。問對於給定的陣列,先開始的玩家能否保證贏得遊戲(如果相等也算先手的玩家贏)。

例如給定陣列為[1, 5, 233, 7],a為開始第一步的玩家。a可以取1或者7,如果a先取1,剩下[5, 233, 7];b可以取5或者7,但不管b取任何元素,a都可以取233,從而a肯定可以贏得遊戲。

分析:先走的玩家贏得遊戲,即要求先走的玩家的元素和大於等於陣列和的一半。

如果按照遊戲的步驟,把陣列從長向短的方向進行,每進行一步都會產生不同的選擇,如果要記錄所有可能的情況,時間複雜度和空間複雜度都比較高。

方法一:可以把這個過程倒過來,對於給定陣列,反過來按照從短到長的方向進行計算。

用dp[i][j]來記錄先手玩家取得的元素和,則 d[i][j] = max(d[i+1][j] + nums[i], d[i][j-1] + nums[j]),其中d[i+1][j]是對手選擇元素之後的結果,由對手來確定,有可能是以下兩種情況之一:d[i+1][j] = d[i+2][j] 或者d[i+1][j] = d[i+1][j-1],同理,d[i][j-1] = d[i+1][j-1]或者d[i][j-1] = d[i][j-2]。由於對手的目的是使先手玩家的和最小,所以d[i+1][j] = min (dp[i + 2][j], dp[i + 1][j - 1]), d[i][j-1] = min (dp[i + 1][j - 1], dp[i][j - 2]) 。因此,dp[i][j] = max( min (dp[i + 1][j - 1], dp[i + 2][ j]) + nums[i], min (dp[i][j - 2], dp[i + 1][ j - 1]) + nums[j]})

(相當於把選元素的過程以逆序進行了,如果按照正序,為了使最後的和最大,每一步選擇的並不一定是使當前和最大的元素;但逆序的過程,從最後一步開始選,每一步都選使當前和最大的元素,到最後一步得到的肯定是最大的和。)

此過程實際上為minmax演算法的實現,從搜尋樹的葉子情況開始(所有可能的搜尋路徑的終點開始),每一步取若是先手的主動權,取最大值,如果是對手的主動權,取最小值。以此類推,直到根節點。

public boolean predictthewinner(int nums) 

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

}return dp[0][n - 1] * 2 >= sum;

}

方法二:使用遞迴的方法
public boolean predictthewinner(int nums) 

private int helper(int nums, int s, int e)

跳躍遊戲一(動態規劃)

給定乙個非負整數陣列,假定你的初始位置為陣列第乙個下標。陣列中的每個元素代表你在那個位置能夠跳躍的最大長度。請確認你是否能夠跳躍到陣列的最後乙個下標。例如 a 2,3,1,1,4 a 2,3 1,1 4 能夠跳躍到最後乙個下標,輸出true a 3,2,1,0,4 a 3,2 1,0 4 不能跳躍到...

暗黑遊戲(動態規劃)

description 暗黑遊戲中,裝備直接決定玩家人物的能力。可以使用pg和rune購買需要的物品。暗黑市場中的裝備,每件有不同的 pg和rune 能力值 最大可購買件數。kid作為暗黑戰網的乙個玩家,當然希望使用盡可能少的pg和rune購買更優的裝備,以獲得最高的能力值。請你幫忙計算出現有支付能...

傳球遊戲 動態規劃

上體育課的時候,小蠻的老師經常帶著同學們一起做遊戲。這次,老師帶著同學們一起做傳球遊戲。遊戲規則是這樣的 n個同學站成乙個圓圈,其中的乙個同學手裡拿著乙個球,當老師吹哨子時開始傳球,每個同學可以把球傳給自己左右的兩個同學中的乙個 左右任意 當老師再次吹哨子時,傳球停止,此時,拿著球沒傳出去的那個同學...