硬币游戏

Alice和Bob发明了一种新的两人游戏。最初,地面放置有一摞共n个硬币( 5 <= n <= 2000 ),从上面数第 i 个硬币的价值为C​​i( 1 <= Ci <= 100000 ),游戏开始后,由Alice先拿走最上层的一枚或两枚硬币,之后Bob再选择拿走最上层的一枚或两枚硬币,两人依此规则交替拾取硬币,当没有硬币可取的时候,游戏就结束了。两个人都希望自己拿到的硬币的价值和尽可能的大。因为Bob非常聪明,现在,Alice希望知道在假设Bob每次都会选择最佳策略时,Alice自己能够拿到的最大价值和是多少?

输入:

        单组用例。

        第一行有正整数n (5 <= n <= 2000)

        之后n行,每行一个整数,第i + 1行的整数代表Ci( 1 <= C<= 100000 )

输出:

        一行,一个整数代表Alice所能拿到的最大价值和。


思路分析:


定状态:问题即为状态
dp[i]表示还剩下i个硬币时,A先手所取得的最大价值。
状态方程
dp[i] = max{a[i]+Σa(1->i-1)-dp[i-1], a[i]+a[i-1]+Σa(1->i-2)-dp[i-2]}
//即分为的两种情况:A先取2个,或者先取1个


#include 
#include 
#define N 2005
using namespace std;

int a[N];
int dp[N];

int sum(int s, int e, int a[])
{
	int ans = 0;
	for (int i = s; i <= e; i++)
		ans += a[i];
	return ans;
}

int main()
{
	int n;
	scanf("%d", &n);
	for (int i = n; i > 0; i--)
		scanf("%d", &a[i]);
	dp[1] = a[1];
	dp[2] = a[1] + a[2];
	for (int i = 3; i <= n; i++)
		dp[i] = max(a[i] + sum(1, i - 1, a) - dp[i - 1], a[i] + a[i - 1] + sum(1, i - 2, a) - dp[i - 2]);
	printf("%d\n", dp[n]);
	return 0;
}


你可能感兴趣的:(动态规划)