有如下乙個雙人遊戲:n(2 <= n <= 100)個正整數的序列放在乙個遊戲平台上,遊戲由玩家1開始,兩人輪流從序列的任意一端取乙個數,取數後該數字被去掉並累加到本玩家的得分中,當數取盡時,遊戲結束。以最終得分多者為勝。
編乙個執行最優策略的程式,最優策略就是使玩家在與最好的對手對弈時,能得到的在當前情況下最大的可能的總分的策略。你的程式要始終為第二位玩家執行最優策略。
輸入格式:
第一行: 正整數n, 表示序列中正整數的個數。
第二行至末尾: 用空格分隔的n個正整數(大小為1-200)。
輸出格式:
只有一行,用空格分隔的兩個整數: 依次為玩家一和玩家二最終的得分。
輸入樣例#1:
64 7 2 9 5 2
輸出樣例#1:
18 11
題目翻譯來自nocow。
usaco training section 3.3
思路:經典的區間型動態規劃的題。
狀態只有2種:從左邊拿和從右邊拿。
假設當前狀態a1,a2,a3,a4,a5,如果第乙個人選最左邊的,則問題轉化為四個數a2,a3,a4,a5,然後第二個人先選,由於題目說第二個人方案也最優,所以選的也是最優方案,即f[i+1][j];先選右邊同理。
f[i][j]表示i~j區間段第乙個人選的最優方案。
所以dp轉移方程為:f[i][j]=max
sum[i][j]其實就等於sum[1][j]-sum[1][i-1],於是我們用乙個s陣列,s[i]表示前1~i個數的和,就好了。
所以dp轉移方程也可寫成f[i][j]=max((s[j]-s[i-1])-f[i+1][j],(s[j]-s[i-1])-f[i][j-1]);
根據dp轉移方程我們可以發現,要得到狀態f[i][j],必須要得到狀態f[i+1][j]和f[i][j-1]。然後我們就可以寫出程式了。
#include#include#include
#include
using
namespace
std;
int n,w[5001],s[5001],f[5001][5001
];int
main()
for(int i=n;i>=1;i--)
for(int j=i+1;j<=n;j++)
f[i][j]=max((s[j]-s[i-1])-f[i+1][j],(s[j]-s[i-1])-f[i][j-1
]); cout
<1][n]<<"
"<1
][n];
}
P2734 遊戲 A Game DP問題)
題目提供者該使用者不存在 標籤usaco 雲端難度普及 提高 時空限制1s 128mb 有如下乙個雙人遊戲 n 2 n 100 個正整數的序列放在乙個遊戲平台上,遊戲由玩家1開始,兩人輪流從序列的任意一端取乙個數,取數後該數字被去掉並累加到本玩家的得分中,當數取盡時,遊戲結束。以最終得分多者為勝。編...
洛谷P4161 遊戲
給出 n 令 nxt x 表示 x 對應的數字。一開始有乙個 1 sim n 的遞增排列,每次數字 x 會變成 nxt x 如此反覆直到該序列再次變回 1 sim n 的遞增排列。設迴圈了 k 次,你需要求出在 nxt 各不相同的情況下,k 有多少種取值。也就是說 nxt 有 n 種方案,對於每一種...
洛谷 P1057 傳球遊戲
題目描述 上體育課的時候,小蠻的老師經常帶著同學們一起做遊戲。這次,老師帶著同學們一起做傳球遊戲。遊戲規則是這樣的 n個同學站成乙個圓圈,其中的乙個同學手裡拿著乙個球,當老師吹哨子時開始傳球,每個同學可以把球傳給自己左右的兩個同學中的乙個 左右任意 當老師在此吹哨子時,傳球停止,此時,拿著球沒有傳出...