P2964 [USACO09NOV]硬币的游戏A Coin Game

题目描述

Farmer John‘s cows like to play coin games so FJ has invented with a new two-player coin game called Xoinc for them.

Initially a stack of N (5 <= N <= 2,000) coins sits on the ground; coin i from the top has integer value C_i (1 <= C_i <= 100,000).

The first player starts the game by taking the top one or two coins (C_1 and maybe C_2) from the stack. If the first player takes just the top coin, the second player may take the following one or two coins in the next turn. If the first player takes two coins then the second player may take the top one, two, three or four coins from the stack. In each turn, the current player must take at least one coin and at most two times the amount of coins last taken by the opposing player. The game is over when there are no more coins to take.

Afterwards, they can use the value of the coins they have taken from the stack to buy treats from FJ, so naturally, their purpose in the game is to maximize the total value of the coins they take. Assuming the second player plays optimally to maximize his own winnings, what is the highest total value that the first player can have when the game is over?

MEMORY LIMIT: 20 MB

农夫约翰的奶牛喜欢玩硬币游戏.

初始时,一个有N枚硬币的堆栈放在地上,从堆顶数起的第i枚硬币的币值 为Ci

开始玩游戏时,第一个玩家可以从堆顶拿走一枚或两枚硬币.如果第一个玩家只拿走堆顶的 一枚硬币,那么第二个玩家可以拿走随后的一枚或两枚硬币.如果第一个玩家拿走两枚硬币,则第二个玩家可以拿走1,2,3,或4枚硬币.在每一轮中,当前的玩家至少拿走一枚硬币,至多拿 走对手上一次所拿硬币数量的两倍.当没有硬币可拿时,游戏结束.

两个玩家都希望拿到最多钱数的硬币.请问,当游戏结束时,第一个玩家最多能拿多少钱 呢?

输入格式

* Line 1: A single integer: N

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

输出格式

* Line 1: A single integer representing the maximum value that can be made by the first player.

输入输出样例

输入 #1

5
1
3
1
7
2

输出 #1

9

说明/提示

There are five coins with the values 1, 3, 1, 7, and 2.

The first player starts by taking a single coin (value 1). The opponent takes one coin as well (value 3). The first player takes two more coins (values 1 and 7 -- total 9). The second player gets the leftover coin (value 2-- total 5).

思路

转自: Twilight_

DP:

1.状态:建立一个二维的状态(i,j)说明拿硬币的权力到达其中一名玩家时,桌面上还剩下编号为1~i(倒序,1为最底下的) 的硬币,

上一名玩家拿走了j枚硬币。

2.下一步的状态:那么这一个玩家在这一轮可以选择拿走1,2,3,4…2*j枚硬币,而他所能获得的最大硬币面值就是1~i所有的硬币面

值之和减去他完成此次操作后(设他取走了k枚硬币)到达状态(i-k,k)的另一名玩家所能获得的最大硬币数。

3.状态的转移:可是因为k的取值范围很大,所以不能直接枚举,不难发现(i,j-1)和(i,j)的状态只相差两种选择的可能,即下一步取走

2*j-1或2*j个硬币的这两种,只需要再比较一次这两种状态即可。

*状态转移方程:dp[i][j]=max(dp[i][j],sum[i]-dp[i-k][k],sum[i]-dp[i-k-1][k+1])(k==2\j-1);

4.答案:答案则是在剩下1~n枚硬币时(初始状态)的dp[n][1](下一步可以选择1枚或两枚硬币)了。

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=5010;

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

原文地址:https://www.cnblogs.com/mysh/p/11633166.html

时间: 2024-10-27 05:34:13

P2964 [USACO09NOV]硬币的游戏A Coin Game的相关文章

洛谷P2964 [USACO09NOV]硬币的游戏A Coin Game

题目描述 Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game called Xoinc for them. Initially a stack of N (5 <= N <= 2,000) coins sits on the ground; coin i from the top has integer value C_i (1 <= C_i <=

[USACO09NOV]硬币的游戏A Coin Game

https://daniu.luogu.org/problemnew/show/P2964 dp[i][j] 表示桌面上还剩i枚硬币时,上一次取走了j个的最大得分 枚举这一次要拿k个,转移到dp[i-k][k] dp[i][j]=max(sum[i]-dp[i-k][k]) 因为 上一次取走j个和取走j-1个 k的取值范围 只相差 2*j-1 和 2*j 所以 直接 dp[i][j]=dp[i][j-1] 然后k分别等于  2*j-1 和 2*j,转移 最后输出dp[n][1],因为先手可以拿1

[luogu2964][USACO09NOV][硬币的游戏A Coin Game]

题目描述 Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game called Xoinc for them. Initially a stack of N (5 <= N <= 2,000) coins sits on the ground; coin i from the top has integer value C_i (1 <= C_i <=

BZOJ 2017: [Usaco2009 Nov]硬币游戏(A Coin Game)

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2017 参考题解:http://www.mamicode.com/info-detail-1582288.html 解:看的时候觉得是动归,然而不会设也不会列,看了半天别人的题解... 首先我们用f[i][j]来表示还剩下后i个硬币要取,上一步取了j个硬币,接下来的步骤中能获得的最大价值. 然后呢,假设在这一步是第一个人取,要取k个,k<=min(2*j,i),很显然,因为第二个人也会取最

洛谷 [P2964] 硬币的游戏

博弈论+dp 依旧是博弈论的壳子,但问的是最大值,所以要dp 设 dp[i][j] 表示该取 i 号硬币,上一次取了 j 个的先手能取的最大值, 因为每次从小到大枚举复杂度太高,所以我们要从 dp[i][i - 1] 转移,每次新加两个状态即可 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using n

bzoj4600 [Sdoi2016]硬币游戏

Description Alice和Bob现在在玩的游戏,主角是依次编号为1到n的n枚硬币.每一枚硬币都有两面,我们分别称之为正面和反面.一开始的时候,有些硬币是正面向上的,有些是反面朝上的.Alice和Bob将轮流对这些硬币进行翻转操作,且Alice总是先手.具体来说每次玩家可以选择一枚编号为x,要求这枚硬币此刻是反面朝上的.对于编号x来说,我们总可以将x写成x=c*2^a*3^b,其中a和b是非负整数,c是与2,3都互质的非负整数,然后有两种选择第一种,选择整数p,q满足a>=p*q,p>

【蓝桥杯】历届试题 翻硬币

  历届试题 翻硬币   时间限制:1.0s   内存限制:256.0MB 问题描述 小明正在玩一个“翻硬币”的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:**oo***oooo 如果同时翻转左边的两个硬币,则变为:oooo***oooo 现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢? 我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求: 输

NIM游戏策略

NIM取子游戏是由两个人面对若干堆硬币(或石子,或..)进行的游戏,游戏由两个人进行,设有k>=1堆硬币,各堆含有n1,n2,n3,n4.....,nk个硬币,游戏的目的就是选取最后剩下的硬币.游戏规则如下: 1)游戏人交替进行游戏: 2)当轮到每个游戏人取子时,选择这些硬币中的一堆,并从所选的堆中取走至少一枚硬币(可以将所选堆中所有硬币全部取走剩下一个空堆). 当所有堆变成空堆时,游戏结束.最后取子的人(即能够取走最后一堆中的所有硬币的人)获胜. 这个问题中的变量是堆数k和各堆的硬币数n1,n

计蒜客 翻硬币 数学题,

https://nanti.jisuanke.com/t/14897 描述: L用硬币玩游戏.他在n*m的矩阵中的每个小格中放一枚硬币,他想将所有的硬币都变成正面向上,但是,他给自己增加一些难度,他只能将整行或者整列的硬币都翻面.当然,他一点也不想做无用功,所以,他想知道当前的状态是否能通过一系列操作后使得所有硬币正面朝上. 输入: 首先是一个T,代表数据的组数:每组数据的第一行给出一个n和m,代表行数和列数:接下来n行,每行由m个数(0或者1),0表示硬币正面朝上,1表示硬币反面朝上: 数据范