题面

题面

题解

观察题目,我们可以发现,这个游戏其实就是不断再把对方挤到一边去,也就是黑子不断往左走,白子不断往右走。

因此可以发现,如果将黑白子按顺序两两配对,那么它们中间的距离会不断缩小,且每次操作只能改变k对黑白子中间的距离,并且每次改变多少没有限制。

那么这就变成了一个kth-nim游戏,因此我们把匹配的黑白子中间的距离当做石子个数,直接按照kth-nim游戏来做即可.

输出方案则要用到DP。

f[i][j]表示DP到二进制的第i位,放j个石头的不合法方案。

那么根据nim游戏,为了保证不合法,我们就要保证二进制上的每一位的1的个数之和整除(k + 1)。

因此我们枚举现在一共已经用了多少个石子,然后枚举当前位(二进制第i位)要用到多少石子。

再用组合数来计算分配方案即可。

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define p 1000000007
#define AC 20100
#define ac 20
#define LL long long LL n, k, d, ans;
LL fac[AC], inv[AC], f[ac][AC], bits[ac];//f[i][j]表示二进制前i位,放j个石子的方案数 LL C(int x, int y){return fac[x] * inv[y] % p * inv[x - y] % p;}
void up(LL &x, LL y)
{
x += y;
if(x < 0) x += p;
if(x >= p) x -= p;
} void pre()
{
scanf("%lld%lld%lld", &n, &k, &d);
inv[0] = inv[1] = fac[0] = bits[1] = 1, k >>= 1;//注意0!= 1
int tmp = n + k;
for(R i = 2; i <= tmp; i ++) inv[i] = (p - p / i) * inv[p % i] % p;
for(R i = 1; i <= tmp; i ++) //求出阶乘表和阶乘逆元表
fac[i] = fac[i - 1] * i % p, inv[i] = inv[i] * inv[i - 1] % p;
for(R i = 2; i <= 15; i ++) bits[i] = bits[i - 1] << 1;
} void work()
{
int maxn = 15, all = n - 2 * k;
f[0][0] = 1;
for(R i = 1; i <= maxn; i ++)
{
for(R j = 0; j <= all; j ++)//枚举当前格子数
{
for(R l = 0; l <= k; l += d + 1)//枚举d + 1的倍数(相比于上次的增量),因为当前位1的个数必须是d + 1的倍数
{//把这l份(d + 1)分配给每一堆石子,但不能拆开任意一堆(不然这个1就不在第i位了)
int have = j - l * bits[i];//上个格子的
if(have < 0) break;//且每堆要么分一个,要么不分,所以份数不能超过堆数
up(f[i][j], f[i - 1][have] * C(k, l) % p);//在k堆里面选l堆出来放
}
}
}//先枚举放了的石子个数,于是就要在剩下的n - i - 2 * k个格子中插入允许相邻的k堆石子 n - i - 2 * k + k = n - i - k
for(R i = 0; i <= all; i ++) up(ans, -C(n - i - k, k) * f[15][i] % p);
up(ans, C(n, k << 1));
printf("%lld\n", ans);
} int main()
{
// freopen("in.in", "r", stdin);
pre();
work();
//fclose(stdin);
return 0;
}

[SDOI2011]黑白棋 kth - nim游戏的更多相关文章

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

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

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

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

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

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

  4. P2490 [SDOI2011]黑白棋

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

  5. BZOJ 2281: [Sdoi2011]黑白棋 (Nim游戏+dp计数)

    题意 这题目有一点问题,应该是在n个格子里有k个棋子,k是偶数.从左到右一白一黑间隔出现.有两个人不妨叫做小白和小黑.两个人轮流操作,每个人可以选 1~d 枚自己颜色的棋子,如果是白色则只能向右移动, ...

  6. BZOJ2281[Sdoi2011]黑白棋&BZOJ4550小奇的博弈——DP+nimk游戏

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

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

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

  8. 【BZOJ2281】【博弈论+DP】 [Sdoi2011]黑白棋

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

  9. [SDOI2011]黑白棋

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

随机推荐

  1. C/C++ 下mysql应用封装(连接增删改查)

    mysql - 初始化 1) mysql_init():初始化数据库 2) mysql_real_connect()(不推荐用Mysql_connect()):连接数据库 详细代码如下: bool d ...

  2. OpenWrt架设nginx php网站

    参考 http://www.vinoca.org/2012/05/31/openwrt%E6%9E%B6%E8%AE%BEnginxphp%E7%BD%91%E7%AB%99/ 一.安装相关包 opk ...

  3. Lua学习笔记(6): 函数

    Lua的函数 函数用于简化程序,当某些工作需要重复执行的时候就可以使用函数减轻工作量(虽然复制粘贴也行) 语法: function 函数名(参数列表) 函数体 return 返回值 end --结束标 ...

  4. 虚拟货币——比特币行情价格分析

    最近挖以太币的朋友们在关注以太坊行情时,一定会发现以太币的价格对比之前上涨了不少.肯定有部分朋友想了解这次上涨的原因,我们特地为此查询了一番.因为比特币相当于虚拟货币中的黄金,它的价格波动会波及到其他 ...

  5. Windows 下在 Python (Anaconda) 中安装 Dlib 库

    0. 引言 介绍在 Windows  操作系统下,在 Python 的 Anaconda 集成环境中,安装 Dlib 库 : 对于不了解源码编译的,或者利用 cmake 方法失败的,可以尝试下此方法: ...

  6. Dsniff简介

    原文发表于:2010-09-25 转载至cu于:2012-07-21 前两天因为看局域网安全的视频中介绍dsniff,也想自己安装下来看看效果.简单的使用没什么难的(高级使用就需要研究文档了),但是安 ...

  7. Python基础灬函数补充(作用域,迭代器,生成器)

    变量作用域 函数里面操作外部变量时,作用域仅限于函数里面. var1 = 123 def func(): var1 = 456 print("函数里:", var1) func() ...

  8. Qt应用程序重启

    重启应用程序是一种常见的操作,在Qt中实现非常简单,需要用到QProcess类一个静态方法: // program, 要启动的程序名称 // arguments, 启动参数 bool startDet ...

  9. Chrome 鲜为人知的秘籍(内部协议)&&Chrome功能指令大全

    楼主以 Chrome 版本 39.0.2171.95 m 为例,耗费2小时的记录: chrome://accessibility 用于查看浏览器当前访问的标签,打开全局访问模式可以查看:各个标签页面的 ...

  10. 过山车 HDU 2063 (二分图匹配裸题)

    Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生 ...