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;
}