博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3105 [cqoi2013]新Nim游戏
阅读量:6307 次
发布时间:2019-06-22

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

Description

\(k\)堆石子,两个人游戏:

  • 首先,A拿走若干堆石子(不能全部拿走)

  • 之后,B拿走若干堆石子(不能全部拿走)

  • 然后从A开始\(Nim\)游戏。

问A能不能取胜。如果能,A第一步至少要拿走多少石子?

Solution

显然可以取胜。A拿的只剩1堆,B不能拿走,A全拿完,B输了。

考虑A第一次拿完之后,剩下的石子在异或意义下必须线性无关。否则B找出一组石子异或为0,A就输掉了。

那么A拿走的石子尽量少等价于剩下的石子尽量多。

也就是求最大权线性无关组,权值即为石子个数。

线性无关组是一个拟阵(遗传性易证,交换性来说,如果两个线性无关组\(X\)\(Y\)\(|X|<|Y|\),那么\(X\)张成的线性空间有\(|X|\)维,\(Y\)张成的线性空间有\(|Y|\)维,后者中必能选出一个元素加到\(|X|\)中线性无关)。

所以我们从大到小判断每堆石子能不能保留即可。

Code

#include 
#include
const int K = 105;int J[32], A[K];bool mark[K];bool cmp(int a, int b) { return b < a; }int main() { int k; scanf("%d", &k); for (int i = 0; i < k; ++i) scanf("%d", &A[i]); std::sort(A, A + k, cmp); long long ans = 0; for (int i = 0, j, l; i < k; ++i) { for (l = 31, j = A[i]; ~l; --l) if ((j >> l) & 1) { if (!J[l]) { J[l] = j; break; } else j ^= J[l]; } if (l == -1) ans += A[i]; } printf("%lld\n", ans); return 0;}

转载于:https://www.cnblogs.com/y-clever/p/8513279.html

你可能感兴趣的文章
机器学习:用初等数学解读逻辑回归
查看>>
如何在 Ubuntu 中管理和使用逻辑卷管理 LVM
查看>>
Oracle原厂老兵:从负面案例看Hint的最佳使用方式
查看>>
把自己Github上的代码添加Cocoapods支持
查看>>
C语言OJ项目参考(2493)四则运算
查看>>
零基础入门深度学习(二):神经网络和反向传播算法
查看>>
find和xargs
查看>>
数据结构例程—— 交换排序之快速排序
查看>>
WKWebView代理方法解析
查看>>
IOS定位服务的应用
查看>>
[SMS&WAP]实例讲解制作OTA短信来自动配置手机WAP书签[附源码]
查看>>
IOS中图片(UIImage)拉伸技巧
查看>>
【工具】系统性能查看工具 dstat
查看>>
基于zepto或jquery的手机端弹出框成功,失败,加载特效
查看>>
php引用(&)
查看>>
Delphi 操作Flash D7~XE10都有 导入Activex控件 shockwave
查看>>
oracle 学习笔记之名词解释
查看>>
MySQL Cluster搭建与测试
查看>>
python数据分析画图体验
查看>>
军规15 确保集成和调用第三方APP
查看>>