【題解】硬幣遊戲
阿新 • • 發佈:2019-05-03
iostream define gis tro sed ostream ron lose return
題目描述
有n個硬幣排成一列,第i個硬幣的價值為ai 。現在小A和小B準備進行一個遊戲。遊戲的規則為:
由小A進行第一個回合,然後每個回合由小A和小B交替進行,直到只剩下一個硬幣為止。
每個回合,該人可以取走這一列硬幣中最左端或最右端的一個硬幣。
小A希望剩下的一個硬幣的價值盡量小,小B希望剩下的一個硬幣的價值盡量大。現在請你求出,當小A和小B都采取最優策略時,剩下一個硬幣的價值是多少。
輸入格式
第一行一個整數n,表示硬幣的總數。 第二行輸入n個整數,分別表示n個硬幣的價值。
輸出格式
輸出一行一個整數,表示剩下的最後一個硬幣的價值。
輸入樣例
5
1 2 3 4 5
輸出樣例
3
數據規模
對於 30% 的數據,$ n \leqslant 3 $。
對於 100%的數據,$ 1\leqslant2000 , 1 \leqslant ai \leqslant 10^{9}$。
題解
容易想到,每個人都能控制對方拿不到哪個硬幣,即控制對方拿哪堆硬幣,那我們按照雙方的遊戲目標來跑這個過程,區間dp即可。
#include <iostream> #include <cstdio> #define MAX_N 2000 using參考程序namespace std; int n; int a[MAX_N + 5]; int dp[MAX_N + 5][MAX_N + 5]; int main() { scanf("%d", &n); for(register int i = 1; i <= n; ++i) { scanf("%d", a + i); } for(register int i = n; i; --i) { dp[i][i] = a[i]; for(register intj = i + 1; j <= n; ++j) { if(n - (j - i + 1) & 1) { dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]); } else { dp[i][j] = min(dp[i + 1][j], dp[i][j - 1]); } } } printf("%d", dp[1][n]); return 0; }
【題解】硬幣遊戲