1. 程式人生 > >【題解】硬幣遊戲

【題解】硬幣遊戲

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 int
j = 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; }
參考程序

【題解】硬幣遊戲