题意

这题目有一点问题,应该是在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. python--接口自动化测试(接口状态)

    本节开始,开始介绍python的接口自动化测试,首先需要搭建python开发环境,到https://www.python.org/下载python 版本直接安装就以了,建议 下载python2.7.1 ...

  2. linux运维工程师常用命令

    1.ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a  列出包括.a开头的隐藏文件的所有文件-A  通-a,但不列出"."和".."-l  列 ...

  3. Istio技术与实践03:最佳实践之sidecar自动注入

    Istio通过对serviceMesh中的每个pod注入sidecar,来实现无侵入式的服务治理能力.其中,sidecar的注入是其能力实现的重要一环(本文主要介绍在kubernetes集群中的注入方 ...

  4. params关键字应用

    params 是C#中的可变参数, params主要的用处是在给函数传参数的时候用,就是当函数的参数不固定的时候.  关于参数数组,需掌握以下几点. (1)在方法声明中的 params 关键字之后不允 ...

  5. Go微服务 grpc的简单使用

    作者:薇文文链接:https://www.jianshu.com/p/20ed82218163来源:简书 准备工作 先安装Protobuf 编译器 protoc,下载地址:https://github ...

  6. stm32 窗口看门狗 WWDG

    窗口看门狗WWDG其实和独立看门狗类似,它是一个7位递减计数器不断的往下递减计数,当减到一个固定值0x40时还不喂狗的话,产生一个MCU复位,这个值叫窗口的下限,是固定的值,不能改变 窗口看门狗(WW ...

  7. elementUI .native修饰符

    用第三方组件或者UI框架会自带自身封装的事件,如keyup等,会覆盖原生的组件而无法起效果 .native 修饰符就是用来注册元素的原生事件而不是组件自定义事件的 如elementUI的:<el ...

  8. 部署在SAP Cloud Platform CloudFoundry环境的应用如何消费SAP Leonardo机器学习API

    Jerry的前一篇文章 如何在Web应用里消费SAP Leonardo的机器学习API 里介绍的例子是Neo测试环境的Web应用消费sandbox版本的机器学习API,url如下: https://s ...

  9. jquery操作select下拉框:取值,赋值,删除

    1.jQuery对select的取值 <select id="test"> <option value ="1">测试1</opt ...

  10. js 跳出for/for in/each/for each 循环

    写本文原因:最近用到了for in,用return true跳出本次循环,执行下次循环, 结果发现程序没有预期效果,经过调试发现误用了return true, 特此笔记,欢迎指正. 注意:return ...