取數遊戲(博弈 動規)

2021-08-31 07:32:45 字數 971 閱讀 4269

有如下乙個雙人遊戲:n個正整數的序列放在乙個遊戲平台上,兩人輪流從序列的兩端取數,每次有數字被乙個玩家取走後,這個數字被從序列中去掉並累加到取走該數的玩家的得分中,當數取盡時,遊戲結束。以最終得分多者為勝。

編乙個執行最優策略的程式,最優策略就是使自己能得到在當前情況下最大的可能的總分的策略。你的程式要始終為兩位玩家執行最優策略。

輸入第1行包括乙個正整數n(2≤n≤100), 表示序列中正整數的個數。輸入第2行包含用空格分隔的n個正整數(1≤所有正整數≤200)。

只有一行,用空格分隔的兩個整數: 依次為先取數玩家和後取數玩家的最終得分。

樣例輸入複製

6 

4 7 2 9 5 2

樣例輸出複製

18 11
sum[i][j]表示從i位到j位所有的和,dp[i][j]表示從i位到j位使自身取到的所有值的最大和

想一下,先手要取掉兩端中的乙個值,此時無論先取者還是後取者都希望自己取的是最優的。

何為最優?

都保證自己會取得保證取完後總和相對大的,如何表示?

對於先手而言,

先取左邊還是右邊?當先手取完,就輪到後手去,後手一定會選擇當前能令他得到最大分數的策略,其實當先手在[x, y]區間兩端取走乙個數,那麼後手面臨兩個狀態[x+1, y]和[x, y-1],先手想要取得最大值,一定會想讓後手取這兩種狀態中的較小值,

即:dp[i][j]=sum[i][j]-min(dp[i+1][j],dp[i][j-1]),後半部分為後者所得和,前者所得和為總和減後者的和。。。。

#include#include#includeusing namespace std;

int a[105],sum[105][105],dp[105][105];

int main()

}printf("%d %d\n",dp[0][n-1],sum[0][n-1]-dp[0][n-1]);

}

動規 多邊形遊戲

多邊形遊戲大概是這樣的 看下面的一幅圖 有乙個多邊形,節點處是數字,邊上是運算子,這裡只考慮 和 兩種,兩個點的數與他們之間的運算子進行運算後的結果數構成新的節點,這樣運算到最後只剩乙個數,我們要求得能夠運算出的最大的數。include include using namespace std int...

博弈 取石子遊戲

兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆中取走任意多的石子 二是可以在兩堆中同時取走相同數量的石子。最後把石子全部取完者為勝者。現在給出初始的兩堆石子的數目,如果輪到你先取,假設雙方都採取最好的策略,問最後你是勝者還是敗者。inp...

動規之 方格取數(dp 四維陣列)

題目描述 設有 n times n n 的方格圖 n le 9 n 9 我們將其中的某些方格中填入正整數,而其他的方格中則放入數字 0。如下圖所示 見樣例 a 00 0000 0000 13006 0000 0070 0000 01400 00021 0004 0000 15000 00014 00...