博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ3105】【CQOI2013】新Nim游戏
阅读量:5051 次
发布时间:2019-06-12

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

Description

  

  传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同)。两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴。可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿。拿走最后一根火柴的游戏者胜利。
  
​  本题的游戏稍微有些不同:在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴。可以一堆都不拿,但不可以全部拿走。第二回合也一样,第二个游戏者也有这样一次机会。从第三个回合(又轮到第一个游戏者)开始,规则和Nim游戏一样。
  
  如果你先拿,怎样才能保证获胜?如果可以获胜的话,还要让第一回合拿的火柴总数尽量小。
  

Input

  

​  第一行为整数\((k(k\le1000)\)。即火柴堆数。第二行包含\(k\)个不超过\(10^9\)的正整数,即各堆的火柴个数。
  

Output

  

​  输出第一回合拿的火柴数目的最小值。如果不能保证取胜,输出-1。
  

Sample Input

  

  6
  
  5 5 6 6 5 5
  

Sample Output

  

  21
  
  
  

Solution

  

  Nim游戏先手必胜的条件是所有每一堆的数量异或和不为0。那么我们现在所要做的,是保留一个集合S,使得这个集合的每一个子集异或和都不为0。这样,不论对手从这个集合中删去哪些子集,剩余的元素异或和都不为0。同时,我们要使得删去的元素尽可能小,即选择保留的元素尽可能大。所以,我们的目的其实是构造一组权值最大的线性基。
  
  我们按照每一堆的火柴数a_i从大到小来贪心,尝试将它加入一个线性基中。如果成功加入,则视之为S中的元素;否则,则视为被舍弃的元素,统计入答案中。
  
  这样,我们就可以构造出一组权值最大的线性基。
  
  至于为什么贪心是正确的,不会出现舍弃权值较大的元素来让某些权值较小的元素顺利加入线性基这种决策,可能要用到拟阵证明,这个坑慢慢补吧。但是貌似如此的线性基的带权问题,大概都可以套用贪心的方法,应该是得益于拟阵的相似证明。
  
  
  
   

Code

  

#include 
#include
using namespace std;const int N=105;int n,a[N]; long long ans;namespace LB{ const int B=30; int a[B]; bool insert(int x){ for(int i=B-1;i>=0;i--) if(x&(1<
=1;i--) if(!LB::insert(a[i])) ans+=a[i]; printf("%lld\n",ans); return 0;}

转载于:https://www.cnblogs.com/RogerDTZ/p/9215482.html

你可能感兴趣的文章
自定义tabbar(纯代码)
查看>>
extjs fieldset 和 radio
查看>>
小程序底部导航栏
查看>>
Codeforces Gym101505G:Orchard Division(扫描线+线段树第k大)
查看>>
ibatis学习笔记
查看>>
18-ES6(1)
查看>>
poj1611 简单并查集
查看>>
tensorflow实现迁移学习
查看>>
Ubuntu 14.04下安装CUDA8.0
查看>>
跨平台开发 -- C# 使用 C/C++ 生成的动态链接库
查看>>
关于Redis处理高并发
查看>>
C# BS消息推送 SignalR介绍(一)
查看>>
asp.net core 系列 16 Web主机 IWebHostBuilder
查看>>
WPF星空效果
查看>>
WPF Layout 系统概述——Arrange
查看>>
PIGOSS
查看>>
几款Http小服务器
查看>>
iOS 数组排序
查看>>
第三节
查看>>
PHP结合MYSQL记录结果分页呈现(比较实用)
查看>>