【bzoj3105】新Nim游戏
Solution
转化一下问题
首先看一下原来的Nim游戏,先手必胜的条件是:每堆数量的异或和不为\(0\)
所以在新的游戏中,如果要保证自己(先手)有必胜策略的话,那必须要保证到一开始先手拿走若干堆之后,后手无法拿走若干堆使得剩下每堆的数量异或和为\(0\),也就是说我们要留下的应该是一个极大线性无关组
线性无关组这个的话我们可以通过线性基解决,具体的话就是如果\(insert\)完了之后这个数被变成了\(0\),那么说明这个数和线性基里面的数线性相关
容易注意到\(insert\)的顺序会有影响,那么现在的问题就是,应该选取哪些数作为线性基(或者说应该按照什么顺序把那堆数插到线性基里)
先把结论摆出来:实际上只要按照从大到小的顺序贪心地加就好了
为什么可以贪心呢?
这里需要借助一个很神奇的东西:Portal-->拟阵
我们设\(n\)个火柴堆的数目为集合\(S\),如果\(S\)的某个子集\(R\)不存在任何一个非空子集异或和为\(0\),那么\(R\in I\)
接下来我们来证明一下\(M=(S,I)\)是一个拟阵
1、首先\(S\)肯定是一个有限集
2、遗传性:设\(A\in I\),则由定义可知\(A\)不存在任何一个非空子集满足异或和为\(0\),所以对于任意\(B \subseteq A\),\(B\)都满足不存在任何一个非空子集异或和为\(0\)(因为\(B\)的子集也是\(A\)的子集),所以\(B\in I\),所以\(I\)是遗传的
3、交换性质:设\(,A,B\in I\),且\(|B|>|A|\),我们现在要证明\(\exists x\in B-A\)使得\(A\cup\{x\}\in I\),这里考虑用反证法:假设对于\(\forall x\in B-A\)均有\(A\cup \{x\}\notin I\),则\(B-A\)中的元素均可以由\(A\)的某个子集的异或和表示,因此我们可以得到结论\(B\)中的所有元素均可以由\(A\)的某个子集的异或和来表示。但是这与我们前面的假设\(|B|>|A|\)是矛盾的,所以假设不成立,得证。
我们将\(M=(S,I)\)看成一个带权拟阵,每个\(S\)中的元素的权值就是对应的堆中火柴的数量,那么运用贪心算法我们就可以在带权拟阵中找出权值最大的基
所以就能直接用贪心做啦
代码大概长这个样子:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int MAXN=110,UP=30;
int a[MAXN];
int n,m;
ll ans;
namespace xxj{
int a[UP+1];
bool insert(int x){
for (int i=UP;i>=0;--i)
if (x&(1<<i)){
if (!a[i]){
a[i]=x;
break;
}
x^=a[i];
}
return x;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d",a+i);
sort(a+1,a+1+n);
ans=0;
for (int i=n;i>=1;--i)
if (!xxj::insert(a[i]))
ans+=a[i];
printf("%lld\n",ans);
}
【bzoj3105】新Nim游戏的更多相关文章
- BZOJ-3105: 新Nim游戏 (nim博弈&线性基)
pro: 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从 ...
- BZOJ3105 新Nim游戏 【拟阵】
题目分析: 我不知道啥是拟阵啊,但有大佬说线性基相关的都是拟阵,所以直接贪心做了. 题目代码: #include<bits/stdc++.h> using namespace std; ; ...
- 【BZOJ3105】新Nim游戏(线性基)
[BZOJ3105]新Nim游戏(线性基) 题面 BZOJ Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以 ...
- 【BZOJ3105】[cqoi2013]新Nim游戏 贪心+线性基
[BZOJ3105][cqoi2013]新Nim游戏 Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个 ...
- BZOJ3105: [cqoi2013]新Nim游戏 博弈论+线性基
一个原来写的题. 既然最后是nim游戏,且玩家是先手,则希望第二回合结束后是一个异或和不为0的局面,这样才能必胜. 所以思考一下我们要在第一回合留下线性基 然后就是求线性基,因为要取走的最少,所以排一 ...
- BZOJ3105: [cqoi2013]新Nim游戏
题解: 线性基?类似于向量上的基底. 此题题解戳这里:http://blog.csdn.net/wyfcyx_forever/article/details/39477673 代码: #include ...
- 【BZOJ-2460&3105】元素&新Nim游戏 动态维护线性基 + 贪心
3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 839 Solved: 490[Submit][Stat ...
- bzoj 3105: [cqoi2013]新Nim游戏 异或高消 && 拟阵
3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 535 Solved: 317[Submit][Stat ...
- 洛谷P4301 [CQOI2013]新Nim游戏
P4301 [CQOI2013]新Nim游戏 题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴. ...
随机推荐
- Python range() 函数用法
函数语法 range(start, stop[, step]) 参数说明: start: 计数从 start 开始.默认是从 0 开始.例如range(5)等价于range(0, 5); stop: ...
- ObjectAnimator实现菜单的弹出(扇形)
用ObjectAnimator 实现菜单的弹出 首先是菜单的图片资源和布局 布局中使用FrameLaout 将菜单唤出对应的imageView放在布局的最后面来隐藏菜单详细内容. <?xml v ...
- C++进阶训练——停车收费系统设计
一.简介 经过一段时间的c++基础学习,是时候做一个较为全面的.运用c++功能的较复杂的项目练练手了. 运用软件:Visual Studio (VS). 题目:c++停车收费系统设计(某本编程书进 ...
- scrapy-redis+selenium+webdriver 部署到linux上
背景:在使用selenium时,在本地使用windows,都会有一个图形界面,但是到了生产环境linux上没有了图形界面怎么部署呢? 解决方案: 1.安装图形化界面,不推荐,因为安装图形化界面会占用很 ...
- 无法找到 ContextLoaderListener 类
问题:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener 原因:Eclips ...
- 无法设置主体sa的凭据
设置允许SQL Server身份登录 1.先用Window方式登陆进去,选择数据库实例,右键选择属性——安全性:把服务器身份验证选项从“Window身份验证模式”改为“SQLServer和Window ...
- python中 try、except、finally 的执行顺序
def test1(): try: print('to do stuff') raise Exception('hehe') print('to return in try') return ...
- 把字符串"3,1,2,4"以","分割拆分为数组,数组元素并按从小到大的顺序排列
package com.wangcf; /** * 把字符串"3,1,2,4"以","分割拆分为数组,数组元素并按从小到大的顺序排列 * @author fan ...
- <<世界是数字的>>读书笔记
<世界是数字的>这本书是大学职业规划老师介绍个我读的,从着本中我学到了很多. 第一章,计算机里有什么.这个问题可以从两方面来看:逻辑上或者说功能上的组成,即每一部分是什么.做什么.怎样做. ...
- centos快速安装lamp
搭建MySQL数据库 使用 yum 安装 MySQL: yum install mysql-server -y 安装完成后,启动 MySQL 服务: service mysqld restart 设置 ...