HDU4701_Game
很有意思,很好的一个题目。
题目的意思是两个人初始状态分别有A和B元,现在有N件可买的商品。两人轮流买,商品必须从左到右买过去,一次可以买若干个。第一个无法买到商品的人输。
一看就知道是博弈题目,但是这并不是什么模型式的博弈题目,其实是转化成递推来做的。
一开始我也不知道到底应该怎么来考虑这个问题,于是就按照博弈的思想用Mex的思路去写这个题目,直到我T了发。
后来在网上看到神牛们写的博客后才发现正确的解法。
其实这个问题应该是这样来考虑的。
首先告诉了你两个人初始的钱数,那么总共的钱数是确定。在买完若干件商品后,一部分的钱数已经花在了买商品上面(先不管是谁买的),另一部分的钱还分别留在两个人的手中。这样如果我们知道当前买完了某件商品后其中一个人的剩余的钱数,那么我们可以根据总钱数不变来推出另一个人手中的钱数。
同时,如果在买某一件商品开始是,ALICE手中只要有x元就有了必胜的策略,那么他手中的钱数如果大于x,显然就也是必胜咯。
有了这两点,我们可以来个递推,解决这个问题。
状态f[i]表示在买第i件商品前,只要先手的人的钱数不少于f[i],那么他就有必胜的策略。
什么意思呢?
我们首先看看,A+B即总钱数,最多能买到多少件商品,显然后面的商品都是没有用的。
然后,对于可买的最后的那件商品n,f[n]=a[n]; 因为根据总钱数,只要他能够买掉最后一件商品,下一个人一定无钱购买后面的商品。
接下来就是从i递推到i-1了。
首先从i-1到i可能有两种情况:
一、第i-1个商品和第i个商品是同一个人购买,这说明要是在购买i-1个商品的时候就有必胜的策略,那么此时他手里的钱数必须不小于a[i-1]+f[i](买完第i-1个商品后,必须至少还剩下f[i]的钱)。
二、第i-1个商品和第i个商品不是同一个人购买,这说明前一个人在购买了i-1个商品后,留下了一个必败态给下一个人去购买第i个商品,这里我们知道对于第i个商品,其必败态就是钱数不足f[i]。这样根据总价值的关系就可以推出这种情况下的f[i-1]了。
综合上面的两种情况,我们知道f[i]就是两种情况中的最小值。
这样逐一递推,到达求出f[1],显然我们只要把f[1]和A比较大小,就可以得出谁胜谁负了。
题目很有意思,以前没做过这种类型的题目。赞一个。
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 1000100
#define ll long long
using namespace std; ll n,m,A,B,l,r,mid,tot;
ll a[maxn],f[maxn],sum[maxn]; ll find()
{
l=,r=n;
if (A+B>=sum[n]) return n;
while (l<r)
{
mid=(l+r)>>;
if (sum[mid]>A+B) r=mid;
else l=mid+;
}
return l-;
} int main()
{
while (scanf("%I64d%I64d%I64d",&n,&A,&B)!=EOF)
{
sum[]=;
tot=A+B;
for (ll i=; i<=n; i++) scanf("%I64d",&a[i]),sum[i]=sum[i-]+a[i];
if (A<sum[])
{
printf("BOB\n");
continue;
}
if (A>=sum[n])
{
printf("ALICE\n");
continue;
}
n=find();
f[n]=a[n];
if (tot-sum[n-]-f[n]>=a[n]) f[n]=tot-sum[n-]-a[n]+; for (int i=n-; i>=; i--)
{
f[i]=a[i]+f[i+];
if (tot-sum[i-]-f[i+]+<f[i]) f[i]=tot-sum[i-]-f[i+]+;
} if (f[]>A) printf("BOB\n");
else printf("ALICE\n");
}
return ;
}
HDU4701_Game的更多相关文章
随机推荐
- 与虚拟机和linux的初次接触
初次接触虚拟机 根据老师所给的资源和教程,虚拟机安装的过程十分顺利. 接下来是在虚拟机上安装linux操作系统我下载了破解版的Ubuntu,也是十分顺利 接下来就是安装虚拟机增强功能,命令有些繁琐,在 ...
- 20155315庄艺霖第三次作业之Linux初体验
Linux初体验 安装Linux三两事 老师的作业要求基于VirtualBox安装Linux系统,我一开始下载了VB但是电脑运行不了,后来看网上的教程下载了VMware,才算开始了我的Linux之旅. ...
- 虚拟机与Linux的初体验
很早的时候就知道虚拟机这个神奇东西的存在,但也仅仅是只闻其名,未见其身.后来在信息安全素质教育的这门课程上,为了做木马实验.暴力破解实验以及邮件窃取实验,这才比较直接的接触到了虚拟机.当我看着在另一个 ...
- mongodb在我这个C#下手眼中-01初识
虽然不是技术大牛,但是组长推荐看一下,而且我们正在做的项目,类似于资源中心,牵扯到各种怪异数据类型不同分库,所以至今都是采用这种方式:①MainData表存所有值,变化最大的分库数据用json存储②j ...
- DSP5509项目之用FFT识别钢琴音调(4)之麦克风输入和Line in输入
1. 麦克风输入需要修改的内容,之前的版本是LINE IN的输入.实现功能,检测麦克风的输入,并且同时在耳机里面播放. #include <csl.h> #include <csl_ ...
- Oracle用户和模式,表空间
oracle 用户与表空间关系 oracle用户与表空间关系用户=商家表=商品表空间=仓库1. 1个商家能有很多商品,1个商品只能属于一个商家2. 1个商品可以放到仓库A,也可以放到仓库B,但不能同时 ...
- Struts 2(七):国际化
基于Struts 2的Web应用国际化开发非常简单,其中Struts 2的国际化包括如下几部分:校验提示信息国际化.类型转换提示信息国际化.Action信息国际化以及JSP页面国际化. 第一节 JSP ...
- [.NET] 使用HttpClient操作HFS (HTTP File Server)
前言 本篇文章介绍如何使用HttpClient操作HFS (HTTP File Server),为自己留个纪录也希望能帮助到有需要的开发人员.关于HTTP File Server的介绍.安装.设定,可 ...
- [深度学习] 使用Darknet YOLO 模型破解中文验证码点击识别
内容 背景 准备 实践 结果 总结 引用 背景 老规矩,先上代码吧 代码所在: https://github.com/BruceDone/darknet_demo 最近在做深度学习相关的项目的时候,了 ...
- Delphi 中的 RectTracker - 原创
本文算是副产品,正品是利用 FFmpeg 从任意视频中生成GIF片段的小程序,写完了就发. V2G 正品已出炉,虽然不大像样,但好歹是能用,请见:用 Delphi 7 实现基于 FFMS2 的视频转 ...