zoukankan      html  css  js  c++  java
  • 【AGC002E】Candy Piles 博弈论

    题目大意

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

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

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

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

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

      (nleq 100000)

    题解

      又是一个打表结论题。

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

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

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

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

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

      

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

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

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    #include<utility>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> 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>());
    	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
    ");
    	else
    		printf("Second
    ");
    	return 0;
    }
    
  • 相关阅读:
    SpringBoot整合redis
    maven dependency全局排除
    Spring Boot程序接收命令行参数
    MySQL8.0.20安装详解
    ITRS/GCRS/J2000坐标系的相互转换
    SpringBoot日记——日志框架篇
    SpringBoot集成log4j,解决log4j.properties不生效问题
    Office
    git下载
    WINDOWS上KAFKA运行环境安装
  • 原文地址:https://www.cnblogs.com/ywwyww/p/8513316.html
Copyright © 2011-2022 走看看