bzoj2017[Usaco2009 Nov]硬币游戏*

bzoj2017[Usaco2009 Nov]硬币游戏

题意:

初始时,一个有N枚硬币的堆栈放在地上,每枚硬币都有一个价值。开始玩游戏时,第一个玩家可以从堆顶拿走一枚或两枚硬币。之后每一轮中,当前的玩家至少拿走一枚硬币,至多拿走对手上一次所拿硬币数量的两倍。当没有硬币可拿时,游戏结束。 两个玩家都希望拿到最多钱数的硬币。求第一个玩家最多能拿多少钱。n≤2000。

题解:

首先有dp方程:f[i][j][0]=max(f[i][k][1]+sum(i-k,i)),1≤k≤min(j*2,i),f[i][j][1]=min(f[i][k][0]),1≤k≤min(j*2,i)。

然而这样会超时。发现所以f[i][k][1]的最大值实际上是f[i][j*2][1]、f[i][j*2-1][1]、f[i][j-1][0]的最大值,f[i][k][0]的最小值也是f[i][j*2][0]、f[i][j*2-1][0]、f[i][j-1][1]的最小值。故可以把dp优化到O(n^2)可过。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 #define maxn 2010
 6 using namespace std;
 7
 8 inline int read(){
 9     char ch=getchar(); int f=1,x=0;
10     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
11     while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
12     return f*x;
13 }
14 int a[maxn],sm[maxn],f[maxn][maxn][2],n;
15 int main(){
16     n=read(); inc(i,1,n)a[i]=read(); for(int i=n;i>=1;i--)sm[n-i+1]=sm[n-i]+a[i];
17     inc(i,1,n)
18         inc(j,1,n){
19             f[i][j][0]=j>1?f[i][j-1][0]:0; int k;
20             k=2*j-1; if(k<=i)f[i][j][0]=max(f[i][j][0],f[i-k][k][1]+sm[i]-sm[i-k]);
21             k=2*j;  if(k<=i)f[i][j][0]=max(f[i][j][0],f[i-k][k][1]+sm[i]-sm[i-k]);
22             f[i][j][1]=j>1?f[i][j-1][1]:0x3fffffff;
23             k=2*j-1; if(k<=i)f[i][j][1]=min(f[i][j][1],f[i-k][k][0]);
24             k=2*j; if(k<=i)f[i][j][1]=min(f[i][j][1],f[i-k][k][0]);
25         }
26     printf("%d",f[n][1][0]); return 0;
27 }

20160830

时间: 2024-10-11 18:01:21

bzoj2017[Usaco2009 Nov]硬币游戏*的相关文章

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),很显然,因为第二个人也会取最

1381 硬币游戏

1381 硬币游戏 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 有一个简单但是很有趣的游戏.在这个游戏中有一个硬币还有一张桌子,这张桌子上有很多平行线(如下图所示).两条相邻平行线之间的距离是1,硬币的半径是R,然后我们来抛硬币到桌子上,抛下之后硬币有时候会和一些直线相交(相切的情况也算是相交),有时候不会. 请你来计算一下抛一次硬币之后,该硬币和直线相交数目的期望. Input 第一行给出一个整数T,表示有T组数据(1<=T<=10000). 第2行到T

HDU 3537 Mock Turtles型翻硬币游戏

题目大意: 每次可以翻1个或者2个或者3个硬币,但要保证最右边的那个硬币是正面的,直到不能操作为输,这题目还有说因为主人公感情混乱可能描述不清会有重复的硬币说出,所以要去重 这是一个Mock Turtles型翻硬币游戏 下面是对这个类型游戏的讲解 约束条件6:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初始编号从0开始. 当N==1时,硬币为:正,先手必胜,所以sg[0]=1. 当N==2时,硬币为:反正,先手必赢,先手操作后可能为:反反或正反,方案数为2,所以sg[1]

51Nod - 1381 硬币游戏

51Nod - 1381 硬币游戏 有一个简单但是很有趣的游戏.在这个游戏中有一个硬币还有一张桌子,这张桌子上有很多平行线(如下图所示).两条相邻平行线之间的距离是1,硬币的半径是R,然后我们来抛硬币到桌子上,抛下之后硬币有时候会和一些直线相交(相切的情况也算是相交),有时候不会. 请你来计算一下抛一次硬币之后,该硬币和直线相交数目的期望. Input 第一行给出一个整数T,表示有T组数据(1<=T<=10000). 第2行到T+1,每行给出一个整数R.(0< R <= 10,00

BZOJ 1770: [Usaco2009 Nov]lights 燈

1770: [Usaco2009 Nov]lights 燈 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 840  Solved: 397[Submit][Status][Discuss] Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望.她希望您能夠幫幫她,把所有的燈都給重新開起來!她才能繼續快樂地

1289 大鱼吃小鱼 1305 Pairwise Sum and Divide 1344 走格子 1347 旋转字符串 1381 硬币游戏

1289 大鱼吃小鱼 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼.从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右).问足够长的时间之后,能剩下多少条鱼? Input 第1行:1个数N,表示鱼的数量(1 <= N <= 100000). 第2 - N + 1行:每行两个数A[i], B[i],中间用空格分隔,分别表示鱼的大小及游动的方向(1 <= A[i] <= 10^9,B[i] = 0 或 1

BZOJ 1770: [Usaco2009 Nov]lights 燈( 高斯消元 )

高斯消元解xor方程组...暴搜自由元+最优性剪枝 ----------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<bitset> using namespace std; const int maxn = 49; int N, Id[max

博弈——翻硬币游戏

转自:http://blog.sina.com.cn/s/blog_8f06da99010125ol.html 翻硬币游戏 一般的翻硬币游戏的规则是这样的: N 枚硬币排成一排,有的正面朝上,有的反面朝上.我们从左开始对硬币按1 到N 编号. 第一,游戏者根据某些约束翻硬币,但他所翻动的硬币中,最右边那个硬币的必须是从正面翻到反面.例如,只能翻3个硬币的情况,那么第三个硬币必须是从正面翻到反面.如果局面是正正反,那就不能翻硬币了,因为第三个是反的. 第二,谁不能翻谁输. 有这样的结论:局面的SG

软工作业2:硬币游戏——代码的分析与改进

目的: Python 程序阅读理解 学习Python 编码风格指南中译版(Google SOC), 改进Python程序 如何设计游戏规则,使得慈善事业可持续. 地铁口放置硬币箱(初始值500硬币),顾客可取.可放.请设计一组规则,使得该钱箱永远有钱取(尽量符合实际) 参考:地铁口钱箱 作业步骤: step 1: fork 老师的仓库 +硬币游戏:http://git.oschina.net/juking2017/Game.git 将其 fork 到自己的码云仓库. step2:clone 到本