题意

这题目有一点问题,应该是在n个格子里有k个棋子,k是偶数.从左到右一白一黑间隔出现.有两个人不妨叫做小白和小黑.两个人轮流操作,每个人可以选 1~d 枚自己颜色的棋子,如果是白色则只能向右移动,如果是黑色只能向左移.移动过程中不能越过其他棋子.每个棋子的移动步数是任意的.不能操作的人就算输.求先手必胜的初始局面数模109+710^9+7109+7的值.

分析

我们把k2\frac k22k​每一对黑白棋之间的距离看作一堆石子,那么问题就转化为了有k2\frac k22k​堆石子,每次可以选1...d1...d1...d堆石子,每一堆随意取多少,没有石子取的算输.

我们把问题转换为总方案减去先手必败的方案.我们先考虑假设每一堆石子只有一个,那么必败状态是?没错,就是石子堆数%(d+1)=0的状态.因为先手不管拿1~d的多少,另一个人都可以拿若干石子使得两人拿的石子数加起来等于(d+1)

那么当每一堆石子不止一个时,把k2\frac k22k​堆石子的石子数用二进制表示,统计每位上的1的个数,若每位上1的个数%(d+1)全为0,则必败.

所以说我们就可以DP了.用f[i][j]f[i][j]f[i][j]表示在二进制中满足了前iii位的1的个数%(d+1)都为0,石子数为jjj的方案数.转移时只用枚举一下这一位上的1的个数是(d+1)的x倍就可以转移了.转移时乘上C(k2,x∗(d+1))C(\frac k2,x*(d+1))C(2k​,x∗(d+1)),表示在k2\frac k22k​堆石子中选哪些来放1.石子数确定了,但在格子上的位置还没有确定,最后还要乘上每个白棋放在哪里.

CODE

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
namespace READ {
inline void read(int &num) {
char ch; while((ch=getchar())<'0'||ch>'9');
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
}
}
using namespace READ;
typedef long long LL;
const int MAXN = 10005;
const int LOG = 15;
const int mod = 1e9+7;
int N, K, D;
LL f[LOG][MAXN], fac[MAXN], inv[MAXN];
inline void Pre() {
fac[0] = fac[1] = inv[0] = inv[1] = 1;
for(int i = 2; i <= N; ++i) inv[i] = 1ll * (mod - mod/i) * inv[mod%i] % mod;
for(int i = 2; i <= N; ++i) fac[i] = fac[i-1] * i % mod, inv[i] = inv[i-1] * inv[i] % mod;
}
inline LL C(int n, int m) {
if(m > n) return 0;
return fac[n] * inv[m] % mod * inv[n-m] % mod;
}
int main () {
read(N), read(K), read(D), Pre(); K>>=1;
f[0][0] = 1;
for(int i = 0, bit = 1; i < LOG-1; ++i, bit<<=1)
for(int j = 0; j <= N-(K<<1); ++j) if(f[i][j])
for(int x = 0; x*(D+1) <= K && j+x*(D+1)*bit <= N-(K<<1); ++x)
f[i+1][j+x*(D+1)*bit] = (f[i+1][j+x*(D+1)*bit] + f[i][j] * C(K, x*(D+1))) % mod;
LL ans = C(N, K<<1);
for(int i = 0; i <= N-(K<<1); ++i) ans = (ans - f[LOG-1][i] * C(N-K-i, K)) % mod;
printf("%lld\n", (ans + mod) % mod);
}

BZOJ 2281: [Sdoi2011]黑白棋 (Nim游戏+dp计数)的更多相关文章

  1. bzoj 2281 [Sdoi2011]黑白棋(博弈+组合计数)

    黑白棋(game) [问题描述] 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色 ...

  2. Bzoj 2281 [Sdoi2011]黑白棋 题解

    2281: [Sdoi2011]黑白棋 Time Limit: 3 Sec  Memory Limit: 512 MBSubmit: 592  Solved: 362[Submit][Status][ ...

  3. BZOJ 2281 Luogu P2490 [SDOI2011]黑白棋 (博弈论、DP计数)

    怎么SDOI2011和SDOI2019的两道题这么像啊..(虽然并不完全一样) 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?i ...

  4. BZOJ 2281: [Sdoi2011]黑白棋(dp+博弈论)

    传送门 解题思路 首先发现可以把相邻的黑白棋子之间的距离看成一堆棋子,那么这个就可以抽象成\(Nim\)游戏每次可以取\(d\)堆这个游戏,而这个游戏的\(SG\)值为\(x\%(d+1)\),那么题 ...

  5. bzoj 2281: [Sdoi2011]黑白棋

    再次,,,,,虚(一开始看错题了,看成一次移动一个棋子,能移动1-d个格子...这样的话有没有大神会做??本蒟蒻就教) 额,,直接%%%%把...http://hzwer.com/5760.html ...

  6. BZOJ2281:[SDOI2011]黑白棋(博弈论,组合数学,DP)

    Description 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 ...

  7. [BZOJ2281][SDOI2011]黑白棋(K-Nim博弈)

    2281: [Sdoi2011]黑白棋 Time Limit: 3 Sec  Memory Limit: 512 MBSubmit: 626  Solved: 390[Submit][Status][ ...

  8. 【BZOJ2281】[SDOI2011]黑白棋(博弈论,动态规划)

    [BZOJ2281][SDOI2011]黑白棋(博弈论,动态规划) 题面 BZOJ 洛谷 题解 先看懂这题目在干什么. 首先BZOJ上面的题面没有图,换到洛谷看题就有图了. 不难发现都相邻的两个异色棋 ...

  9. P2490 [SDOI2011]黑白棋

    P2490 [SDOI2011]黑白棋 题意 一个 \(1*n\) 的棋盘上,A 可以移动白色棋子,B 可以移动黑色的棋子,其中白色不能往左,黑色不能往右.他们每次操作可以移动 1 到 \(d\) 个 ...

随机推荐

  1. bs4解析

    介绍:将一个html文档转换成BeautifulSoup对象,然后通过对象的方法或属性查找指定的节点内容 转换本地文件: ​ soup = BeautifulSoup(fp,'lxml') fp为文档 ...

  2. Python【编码】

    编码 ————————————————————————————————让只认识0和1的计算机,能够理解我们人类使用的语言符号,并且将数据转换为二进制进行存储和传输 人类语言到计算机语言转换的形式,就叫 ...

  3. Base64编码为什么会使数据量变大

    现在工作中把视频转成base64发现数据量过大无法下载. 1.为什么base64编码会使数据量变大呢? Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码.它将需要编码的数据 ...

  4. centos源码安装nginx

    1.安装依赖 nginx对以下工具包有依赖,我们可以一键安装,命令: yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-dev ...

  5. [书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型

    本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解J ...

  6. css滑动门技术

    滑动门的核心技术: 为了使各种特殊形状的背景能够自适应元素中文本内容的多少,以使自由拉伸滑动 利用css精灵(主要是背景位置)和盒子padding撑开宽度,以便适应不同字数的导航栏 一般经典布局 &l ...

  7. 全面聊聊JavaScript的浅拷贝和深拷贝

    一.背景      首先我们可以看下面这段简单的代码: var obj = {name:'程序猿',sex:'男'}; var arr = ['程序猿','程序媛']; var copyobj = o ...

  8. Visual Studio快捷键使用

    1. 注释相关     添加注释:Ctrl + K,C     取消注释:Ctrl + K,U 2. 格式化相关     格式化代码:Ctrl + K,D 3. 智能提示相关     Ctrl + J

  9. ASE19团队项目 beta阶段 model组 scrum7 记录

    本次会议于12月10日,19时30分在微软北京西二号楼sky garden召开,持续10分钟. 与会人员:Jiyan He, Lei Chai, Linfeng Qi, Xueqing Wu, Kun ...

  10. 《浏览器工作原理与实践》<10>作用域链和闭包 :代码中出现相同的变量,JavaScript引擎是如何选择的?

    在上一篇文章中我们讲到了什么是作用域,以及 ES6 是如何通过变量环境和词法环境来同时支持变量提升和块级作用域,在最后我们也提到了如何通过词法环境和变量环境来查找变量,这其中就涉及到作用域链的概念. ...