USACO 2010 Dec Silver 2.Treasure Chest 简单博弈 DP

Description

Bessie and Bonnie have found a treasure chest full of marvelous gold coins! Being cows, though, they can't just walk into a store and buy stuff, so instead they decide to have some fun with the coins.

The N (1 <= N <= 5,000) coins, each with some value C_i (1 <= C_i <= 5,000) are placed in a straight line. Bessie and Bonnie take turns, and for each cow's turn, she takes exactly one coin off of either the left end or the right end of the line. The game ends when there are no coins left.
Bessie and Bonnie are each trying to get as much wealth as possible for themselves. Bessie goes first. Help her figure out the maximum value she can win, assuming that both cows play optimally.

Consider a game in which four coins are lined up with these values:

               30   25   10   35

Consider this game sequence:

 

                           Bessie    Bonnie       New Coin
Player   Side   CoinValue   Total     Total         Line
Bessie   Right     35        35         0       30  25  10
Bonnie   Left      30        35        30         25  10
Bessie   Left      25        60        30           10
Bonnie   Right     10        60        40           --

This is the best game Bessie can play.

Input
* Line 1: A single integer: N

* Lines 2..N+1: Line i+1 contains a single integer: C_i

Output
* Line 1: A single integer, which is the greatest total value Bessie can win if both cows play optimally.

Sample Input
4
30
25
10
35

Sample Output
60

题意:一排硬币,两人轮流从左端或右端取一枚硬币,每个硬币都有一定价值,问先手能获得的最大总价值。

最近有点喜欢上这种简单博弈论(或是DP)了呢~

设f[j][i]表示还剩i枚硬币,就是从j到j+i-1这段区间的硬币,由于是两个人轮流取,所以i可以简化为i&1,很容易得到状态转移方程:

f[j][i&1]=sum[i+j-1]-sum[j-1]-min(f[j+1][i&1^1],f[j][i&1^1])

也就是用从j到i+j-2这段区间和j+1到i+j-1这段区间取更新j到i+j-1这段区间,最后答案就是f[1][n&1]

代码:

#include<stdio.h>
int s[5010],f[5010][2];
int n;
int min(int x,int y)
{
	return x<y?x:y;
}
int main()
{
	scanf("%d",&n);
	int i,j,c;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&c);
		s[i]=s[i-1]+c;
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n-i+1;j++)
		{
			f[j][i&1]=s[i+j-1]-s[j-1]-min(f[j+1][i&1^1],f[j][i&1^1]);
		}
	}
	printf("%d",f[1][n&1]);
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值