【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游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴. ...
随机推荐
- 【Linux 运维】 date的使用
date的使用 一.常用时间格式 #年.月.日 四位年大写,其余小写 [root@localhost ~]# date +%Y #长格式显示四位数年 [root@localhost ~]# date ...
- Python多重赋值
可以将变量名视对象的一个链接 >>>foo1 = foo2 = 4.3 >>>foo1 is foo2 True >>>foo1 = 4.3 &g ...
- Beta阶段第2周/共2周 Scrum立会报告+燃尽图 04
此作业要求参见https://edu.cnblogs.com/campus/nenu/2018fall/homework/2412 版本控制地址 [https://git.coding.net/ ...
- struts常量<constant>说明
1.<constant name="struts.action.extension" value="do" />这个时候访问action都必须加.d ...
- c# 导入第三方插件(例如pdf控件),莫名有时候成功有时候出错
问题情境: 正如标题所述: 解决办法: 怀疑是adobe acrobat 9 pro安装文件出错:重新安装,成功. 在这过程中,尝试过福听阅读器,adobe reader等,均正常. 注:1.第三方的 ...
- struts2--文件上传类型3
拦截器栈在<package>标签内 <action>标签外配置 如上我们如果把它定义成默认拦截器的话就不需要在 <action>标签中引入,没有的话需要引入拦截器 ...
- BundleCollection学习(一)
工作中有同事提到了mvc4提供了css,js压缩功能.类BundleCollection所以搜集资料记录学习下. 学习中………… MVC中用 BundleCollection 压缩CSS时图片路径问题 ...
- sed条件不修改匹配
sed '/^echo/!s/text/subtext/g' 如果是以echo开始行首的行就不进行替换. 参考sed substitution conditional
- Struts2(四)
以下内容是基于导入struts2-2.3.32.jar包来讲的 1.struts2配置文件加载的顺序 struts2的StrutsPrepareAndExecuteFilter拦截器中对Dispatc ...
- BOM对象属性定时器的调用
使count中的内容,自动切换 <body> <h1 id="count"></h1> </body> //获取count var ...