[SDOI2019]移动金币(博弈论+阶梯Nim+按位DP)
首先可以把问题转化一下:m堆石子,一共石子数不超过(n-m)颗,每次可以将一堆中一些石子推向前一堆,无法操作则失败,问有多少种方法使得先手必胜?
然后这个显然是个阶梯Nim,然后有这样的结论:奇数层异或和为0。具体证明:参考这篇博客,当然不是我写的。如果不知道结论,里面有例题POJ1704可以做一下。
然后直接DP显然会T飞,考虑一个按位DP的技巧,f[i][j]表示确定前i位异或起来为0,剩下j个棋子的方案数。组合数相乘转移,注意一些细节即可。复杂度O(nmlogn)
#include<bits/stdc++.h>
using namespace std;
const int N=,mod=1e9+;
int n,m,ans,f[][N],fac[N],inv[N];
int C(int a,int b){return 1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;}
int main()
{
cin>>n>>m;
fac[]=inv[]=inv[]=;for(int i=;i<=n+m;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=;i<=n+m;i++)fac[i]=1ll*fac[i-]*i%mod,inv[i]=1ll*inv[i-]*inv[i]%mod;
ans=C(n,m),n-=m;
f[][n]=;
for(int i=;~i;i--)
for(int j=;j<=n;j++)
for(int k=;j+(*k<<i)<=n&&k<=(m+)/;k++)
f[i][j]=(f[i][j]+1ll*f[i+][j+(*k<<i)]*C((m+)/,*k))%mod;
for(int i=;i<=n;i++)ans=(ans-1ll*f[][i]*C(i+m/,m/)%mod+mod)%mod;
cout<<ans;
}
[SDOI2019]移动金币(博弈论+阶梯Nim+按位DP)的更多相关文章
- 【洛谷5363】[SDOI2019] 移动金币(动态规划)
点此看题面 大致题意: 有\(n\)个格子,让你摆放\(m\)个金币.二人博弈,每次选择一个金币向左移任意格,无法移动者输.问有多少种方案使先手必胜. 阶梯\(Nim\) 阶梯\(Nim\)的基本模型 ...
- Luogu P5363 [SDOI2019]移动金币
话说这题放在智推里好久了的说,再不写掉对不起自己233 首先你要知道一个叫做阶梯Nim的东西,具体的可以看这篇博客 那么我们发现这和这道题的关系就很明显了,我们把两个金币之间的距离看作阶梯Nim的每一 ...
- [SDOI2019] 移动金币
分析 阶梯NIM模型:共有m+1堆石子,石子总数不超过n-m,求必胜的,即奇数堆石子数目异或和非零的局面数.补集转化,答案C(n,m)-奇数堆石子数目异或和位0的局面数. 可以想到按位dp,设f[i, ...
- [VIJOS2055][SDOI2019]移动金币:DP+组合数学
分析 显然可以转化为阶梯nim. 于是问题转化为了对于所有\(i \in [0,n-m]\),求长度为\(\lfloor\frac{m+1}{2}\rfloor\),和为\(i\),异或和非\(0\) ...
- POJ 1704 Georgia and Bob [阶梯Nim]
题意: 每次可以向左移动一个棋子任意步,不能跨过棋子 很巧妙的转化,把棋子间的空隙看成石子堆 然后裸阶梯Nim #include <iostream> #include <cstdi ...
- BZOJ 1115: [POI2009]石子游戏Kam [阶梯NIM]
传送门 有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必胜 ...
- 阶梯Nim问题
问题形式 有\(n\)个位置\(1...n\),每个位置上有\(a_i\)个石子.有两个人轮流操作.操作步骤是:挑选\(1...n\)中任一一个存在石子的位置\(i\),将至少1个石子移动至\(i-1 ...
- luoguP3480 [POI2009]KAM-Pebbles 阶梯Nim
将序列差分并翻转之后,变成了阶梯\(Nim\)的模板题 QAQ #include <cstdio> #include <cstring> #include <iostre ...
- Georgia and Bob POJ - 1704 阶梯Nim
$ \color{#0066ff}{ 题目描述 }$ Georgia and Bob decide to play a self-invented game. They draw a row of g ...
随机推荐
- 四、CI框架之通过URL路径访问C中的函数
一.在C中写一个test001函数 二.在路径http://127.0.0.1/CodeIgniter-3.1.10/index.php/welcome/test001中访问 不忘初心,如果您认为这篇 ...
- Linux 压缩解压操作
Linux 压缩解压操作 Linux解压文件到指定目录 tar在Linux上是常用的打包.压缩.加压缩工具,他的参数很多,折里仅仅列举常用的压缩与解压缩参数 参数:-c :create 建立压缩档案的 ...
- JavaScript把两个数组对象合并成一个一一对应的数组对象
合并数组或者对象在数组或对象前面加...,是es6的新写法,然后数组的map方法会返回数组. var obj1 = [{ , "model": "XQG70-S1208F ...
- JAVA中汉字的Compare排序
当调用String.compare方法的时候,比较的是Unicode码,并不能对汉字进行准确的排序,所以汉字比较时会出现比较混乱的结果. java.text.Collator类中有一个getInsta ...
- VS2013 配置Mysql
1.添加mysql.h 对着项目右键,选择properties 双击C/C++,选择General,看到Additional Include Directories 编辑 点击文件夹的按钮 点击... ...
- h5-transform二维变换-扑克牌小案例
html代码:6张扑克牌 <div class="pkBox"> <img src="../img/pk1.jpg" alt="&q ...
- SDWebImage清理缓存
[[SDImageCache sharedImageCache] getSize]//计算缓存的大小,单位B float tmpSize = [[SDImageCache sharedImageCac ...
- 一键分享mob,方法二
2.快速生成项目http://wiki.mob.com/android-sharesdk完整的集成文档/ 修改目标项目名称和项目的包名: 由于直接复制jar包和资源的集成方式比较麻烦,ShareSDK ...
- eclipse启动tomcat出现8080,8009,8005端口被占用的问题
有时候我们在eclipse中启动项目时,Tomcat服务器会报错,显示8080.8009.8005这几个端口被占用,此时你用debug启动项目时会发现不管用,console控制台什么信息也没有,此时产 ...
- linux配置词典goldendict
在mint 18下使用通过, ubuntu 类似. 方法: 通过软件中心安装goldendict,或者 sudo apt install goldendict 通过网页抓取程序, 见附录 下载朗道词典 ...