[英]Converting this recursive solution to DP
給定一堆整數,玩家輪流從堆棧頂部移除1,2或3個數字。 假設對手以最佳方式進行游戲並且您先選擇,我想出了以下遞歸:
int score(int n) {
if (n <= 0) return 0;
if (n <= 3) {
return sum(v[0..n-1]);
}
// maximize over picking 1, 2, or 3 + value after opponent picks optimally
return max(v[n-1] + min(score(n-2), score(n-3), score(n-4)),
v[n-1] + v[n-2] + min(score(n-3), score(n-4), score(n-5)),
v[n-1] + v[n-2] + v[n-3] + min(score(n-4), score(n-5), score(n-6)));
}
基本上,在每個級別比較選擇1,2或3的結果然后你的對手選擇1,2或3。
我想知道如何將其轉換為DP解決方案,因為它顯然是指數級的。 我正在努力解決這樣一個事實:它有三個維度:你的選擇數,對手選擇數和子問題大小,即,它似乎是table[p][o][n]
的最佳解決方案需要維護,其中p
是您選擇的值的數量, o
是您的對手選擇的數字, n
是子問題的大小。
我真的需要3個尺寸嗎? 我已經看到了類似的問題: http : //www.geeksforgeeks.org/dynamic-programming-set-31-optimal-strategy-for-a-game/ ,但似乎無法適應它。
這是問題可以轉換成DP的方式: -
score[i] = maximum{ sum[i] - score[i+1] , sum[i] - score[i+2] , sum[i] - score[i+3] }
這里score[i] means max score generated from game [i to n]
其中v[i] is top of stack
。 sum[i] is sum of all elements on the stack from i onwards
。 sum[i]
可以使用O(N)中的單獨DP來評估。 可以使用O(N)中的表來解決上述DP
編輯: - 以下是JAVA中的DP解決方案: -
public class game {
static boolean play_game(int[] stack) {
if(stack.length<=3)
return true;
int[] score = new int[stack.length];
int n = stack.length;
score[n-1] = stack[n-1];
score[n-2] = score[n-1]+stack[n-2];
score[n-3] = score[n-2]+stack[n-3];
int sum = score[n-3];
for(int i=n-4;i>=0;i--) {
sum = stack[i]+sum;
int min = Math.min(Math.min(score[i+1],score[i+2]),score[i+3]);
score[i] = sum-min;
}
if(sum-score[0]<score[0])
return true;
return false;
}
public static void main(String args[]) {
int[] stack = {12,1,7,99,3};
System.out.printf("I win => "+play_game(stack));
}
編輯:-
要獲得DP解決方案,您需要根據自身的較小實例可視化問題解決方案。 例如,在這種情況下,當兩個玩家都在最佳地玩時,在第一個玩家做出的選擇之后,第二個玩家也獲得剩余堆棧的最佳分數,該剩余堆棧是第一個的子問題 。 這里唯一的問題是如何再次表示它。 要解決DP,必須首先根據子問題定義遞歸關系 , 子問題以任何計算方式在當前問題之前。 現在我們知道,無論第二名球員獲勝,第一名球員如此有效地輸掉第一名球員獲得total sum - score
第二名球員total sum - score
。 作為第二個玩家也能以最佳方式進行游戲,我們可以在遞歸方面表達解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.