[BZOJ2281][SDOI2011]黑白棋(K-Nim博弈)
2281: [Sdoi2011]黑白棋
Time Limit: 3 Sec Memory Limit: 512 MB
Submit: 626 Solved: 390
[Submit][Status][Discuss]Description
小A和小B又想到了一个新的游戏。这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色。最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同。小A可以移动白色棋子,小B可以移动黑色的棋子,他们每次操作可以移动1到d个棋子。每当移动某一个棋子时,这个棋子不能跨越两边的棋子,当然也不可以出界。当谁不可以操作时,谁就失败了。小A和小B轮流操作,现在小A先移动,有多少种初始棋子的布局会使他胜利呢?Input
共一行,三个数,n,k,d。Output
输出小A胜利的方案总数。答案对1000000007取模。
Sample Input
10 4 2Sample Output
182HINT
1<=d<=k<=n<=10000, k为偶数,k<=100。
Source
很有意思的一道博弈题,可惜HZWER学长给出了反例。
那么这一题通过手玩可以发现,最终状态必定是所有棋子全部扎堆在棋盘左端或右端,棋子之间没有间隙。不过仔细观察可以发现,可能在游戏状态中会出现所有棋子扎堆但不在棋盘一端的情况,其实那个时候就已经决定了最终的胜负。因为只要一方朝自己来的方向走了,则另一方必定能也往那边走一步,最终会步步紧逼直到走到棋盘一端。
根据这一点,感性理解一下,这个游戏就是一个把对方棋子“怼”过去的过程,谁怼赢了就是胜者。所以从一开始双方都一定拼尽全力往对面怼,所以有一个结论:先手不可能往左走,后手不可能往右走。
这样这个问题就变成了一个取石子游戏,每对相邻的白子和黑子之间的格子数是石子数(显然共有K/2堆石子),每人每次选不超过k堆取一个石子。
这个问题叫K-Nim,结论是:将所有石子数转成二进制,如果对于每一位二进制,这一位上为1的石子堆数都能被k+1整除则为必败态,否则为必胜态。
证明主要思路是: 1.最终态二进制每一位都为0必为必败态。2.只要有某位的1的个数不被k+1整除,则必然有一种走法使每一位都被整除。 3.如果每一位都被k+1整除,则无论怎么走都不可能使得每一位都仍然能被整除。
这三点分别保证了:最终态是必败态。必胜态必定能走到必败态。必败态只能走到必胜态。
详细证明:http://blog.csdn.net/weixinding/article/details/7321139
这样,我们分别用了“寻找最终态”和“模仿”的技巧将问题转化为了K-Nim问题。回到这一题,最终答案=总方案数-必败态的方案数。
设$f_{i,j}$表示前$i$个二进制位共放了$j$个石子的方案数,则$$ans=C_n^K-\sum_{i=0}^{n-K} f_{s,i}*C_{n-i-K/2}^{K/2}$$s为最高位的1,这里取15就够了。
考虑$f$的转移方程即可:$$f_{i+1,j+k*(d+1)*(1<<i)}\ \ +=\ \ f_{i,j}*C_{K/2}^{k*(d+1)}$$
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std; const ll N=,mod=;
ll tot,ans,bin[],c[N][],f[][N];
int n,K,d,p; void add(ll &x,ll y){ x=(x+y)%mod; }
void pre(){
rep(i,,n) c[i][]=;
rep(i,,n) rep(j,,min(*K,i)) c[i][j]=(c[i-][j]+c[i-][j-])%mod;
}
int C(int n,int m){ if (m>n-m) m=n-m; return c[n][m]; } int main(){
freopen("bzoj2281.in","r",stdin);
freopen("bzoj2281.out","w",stdout);
bin[]=; rep(i,,) bin[i]=bin[i-]<<;
scanf("%d%d%d",&n,&K,&d); K>>=;
pre(); f[][]=;
rep(i,,) rep(j,,n-*K)
for (int k=; k*(d+)<=K && j+k*(d+)*bin[i]<=n-*K; k++)
add(f[i+][j+k*(d+)*bin[i]],f[i][j]*C(K,k*(d+)));
rep(i,,n-*K) add(ans,f[][i]*C(n-i-K,K));
tot=C(n,K*); printf("%lld\n",(tot-ans+mod)%mod);
return ;
}
[BZOJ2281][SDOI2011]黑白棋(K-Nim博弈)的更多相关文章
- BZOJ2281[Sdoi2011]黑白棋&BZOJ4550小奇的博弈——DP+nimk游戏
题目描述 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小A可以移动白色 ...
- BZOJ2281:[SDOI2011]黑白棋(博弈论,组合数学,DP)
Description 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 ...
- [SDOI2011]黑白棋 kth - nim游戏
题面 题面 题解 观察题目,我们可以发现,这个游戏其实就是不断再把对方挤到一边去,也就是黑子不断往左走,白子不断往右走. 因此可以发现,如果将黑白子按顺序两两配对,那么它们中间的距离会不断缩小,且每次 ...
- BZOJ2281 [SDOI2011]黑白棋 【dp + 组合数】
题目 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小A可以移动白色棋子 ...
- bzoj2281 [Sdoi2011]黑白棋
一眼$nimk$游戏,后来觉得不对劲,看了黄学长博客发现真的不是$nimk$. 就当是$nimk$做吧,那么我们要保证每一位上一的个数都是$d+1$的倍数. $dp$:$f[i][j]$表示从低到高第 ...
- 【BZOJ2281】[SDOI2011]黑白棋(博弈论,动态规划)
[BZOJ2281][SDOI2011]黑白棋(博弈论,动态规划) 题面 BZOJ 洛谷 题解 先看懂这题目在干什么. 首先BZOJ上面的题面没有图,换到洛谷看题就有图了. 不难发现都相邻的两个异色棋 ...
- Bzoj 2281 [Sdoi2011]黑白棋 题解
2281: [Sdoi2011]黑白棋 Time Limit: 3 Sec Memory Limit: 512 MBSubmit: 592 Solved: 362[Submit][Status][ ...
- P2490 [SDOI2011]黑白棋
P2490 [SDOI2011]黑白棋 题意 一个 \(1*n\) 的棋盘上,A 可以移动白色棋子,B 可以移动黑色的棋子,其中白色不能往左,黑色不能往右.他们每次操作可以移动 1 到 \(d\) 个 ...
- bzoj 2281 [Sdoi2011]黑白棋(博弈+组合计数)
黑白棋(game) [问题描述] 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色 ...
随机推荐
- java对象与json互转
package com.liveyc; import java.io.StringWriter; import org.junit.Test; import com.fasterxml.jackson ...
- Django之利用ajax实现图片预览
利用ajax实现图片预览的步骤为: 程序实现的方法为: 方法一: upload.html <!DOCTYPE html> <html lang="en"> ...
- long类型的数据转化为时间
long time = 111111111111111111111:SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm: ...
- 安装node-sass的正确姿势【转】
安装 node-sass 的时候总是会各种不成功,今天我琢磨了一会儿总算知道要怎么解决了. 首先要知道的是,安装 node-sass 时在 node scripts/install 阶段会从 gith ...
- ogg数据初始化历程记录
之前,源端数据表结构发生改变,不知道前面的同事是怎么搞得(生成的数据定义文件不对,还是没有把进程启动),造成进程停止20天,然后重启复制进程,对比源端和目标端数据有差异(总共差10000多条数据),问 ...
- PyCharm 自定义文件和代码模板
PyCharm提供了文件和代码模板功能,可以利用此模板来快捷新建代码或文件.比如在PyCharm中新建一个html文件,新的文件并不是空的,而是会自动填充了一些基础的必备的内容,就像这样: <! ...
- Appium 1.6.3使用的自动化测试引擎
automationName项的值: Appium:默认值. Selendroid:安卓2.3(API 9)-4.1(API 16)版本使用. UiAutomator2:最新安卓版本. XCUITes ...
- centos上git搭建
1 git的安装需要一些包: yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-Ex ...
- 杂乱的code
/*o(n)的堆化方法*/ void myjust(vector<int>& A,int i){ int l=i*2+1; int r=i*2+2; int minn=i; if( ...
- 版本控制软件——tortoiseSVN的基础使用
零 基本功能介绍... 2 一 安装及下载client端... 2 二 登陆和文件下载... 2 三 新增档案及目录到服务器中... 4 四 文件对比... 13 4.1 文件回溯... 13 4.2 ...