博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【AGC002E】Candy Piles 博弈论
阅读量:5262 次
发布时间:2019-06-14

本文共 1092 字,大约阅读时间需要 3 分钟。

题目大意

  有\(n\)堆糖果,第\(i\)堆有\(a_i\)个。

  两个人轮流决策,决策分为两种:

   1.选择糖果数最多的一堆糖果,并把这堆糖全吃了。

   2.在每堆非空的糖果堆里拿一颗糖吃掉。

  吃掉最后一颗糖的人输。问你先手必胜还是先手必败。

  \(n\leq 100000\)

题解

  又是一个打表结论题。

  先把\(a_i\)从大到小排序。

  设\(f_{i,j}\)为删掉前\(i\)大,每堆删掉\(j\)个后是先手必胜还是先手必败。先把所有的\(f_{i,j}\)算出来。

  如果都删完了,就先手必胜。

  打个表可以发现,一条斜线上的结果相同。

  这个结论还是挺好证的。这里就不证了。

  1097689-20180306111749203-1034414273.png

  直接找到\((0,0)\)对应的是哪个点\((i,i)\),算出这个点到上方和右方轮廓的距离,只要有一个是偶数,就先手必胜。

  时间复杂度:\(O(n)\)

代码

#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair
pii;int a[100010];int main(){#ifdef DEBUG freopen("b.in","r",stdin); freopen("b.out","w",stdout);#endif int n; int i; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1,greater
()); int ans; a[0]=a[1]; for(i=0;i<=n;i++) if(a[i+1]<=i) { ans=(a[i]-i)&1; int j=i+1; while(j<=n&&a[j]==i) j++; if((j-i+1)&1) ans=1; break; } if(ans) printf("First\n"); else printf("Second\n"); return 0;}

转载于:https://www.cnblogs.com/ywwyww/p/8513316.html

你可能感兴趣的文章
简单的数据库操作
查看>>
Redmine
查看>>
帧的最小长度 CSMA/CD
查看>>
树状数组及其他特别简单的扩展
查看>>
普通求素数和线性筛素数
查看>>
PHP截取中英文混合字符
查看>>
【洛谷P1816 忠诚】线段树
查看>>
电子眼抓拍大解密
查看>>
poj 1331 Multiply
查看>>
tomcat7的数据库连接池tomcatjdbc的25个优势
查看>>
Html 小插件5 百度搜索代码2
查看>>
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
查看>>
java 常用命令
查看>>
卷积中的参数
查看>>
51nod1076 (边双连通)
查看>>
Item 9: Avoid Conversion Operators in Your APIs(Effective C#)
查看>>
深入浅出JavaScript(2)—ECMAScript
查看>>
ViewPager的onPageChangeListener里面的一些方法参数:
查看>>
Jenkins关闭、重启,Jenkins服务的启动、停止方法。
查看>>
CF E2 - Array and Segments (Hard version) (线段树)
查看>>