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 2

Sample Output

182

HINT

1<=d<=k<=n<=10000, k为偶数,k<=100。

Source

stage 2 day1

很有意思的一道博弈题,可惜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)}$$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define rep(i,l,r) for (int i=l; i<=r; i++)
 5 typedef long long ll;
 6 using namespace std;
 7
 8 const ll N=10010,mod=1000000007;
 9 ll tot,ans,bin[25],c[N][205],f[25][N];
10 int n,K,d,p;
11
12 void add(ll &x,ll y){ x=(x+y)%mod; }
13 void pre(){
14     rep(i,0,n) c[i][0]=1;
15     rep(i,1,n) rep(j,1,min(2*K,i)) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
16 }
17 int C(int n,int m){ if (m>n-m) m=n-m; return c[n][m]; }
18
19 int main(){
20     freopen("bzoj2281.in","r",stdin);
21     freopen("bzoj2281.out","w",stdout);
22     bin[0]=1; rep(i,1,15) bin[i]=bin[i-1]<<1;
23     scanf("%d%d%d",&n,&K,&d); K>>=1;
24     pre(); f[0][0]=1;
25     rep(i,0,14) rep(j,0,n-2*K)
26         for (int k=0; k*(d+1)<=K && j+k*(d+1)*bin[i]<=n-2*K; k++)
27             add(f[i+1][j+k*(d+1)*bin[i]],f[i][j]*C(K,k*(d+1)));
28     rep(i,0,n-2*K) add(ans,f[15][i]*C(n-i-K,K));
29     tot=C(n,K*2); printf("%lld\n",(tot-ans+mod)%mod);
30     return 0;
31 }

转载于:https://www.cnblogs.com/HocRiser/p/8583681.html

[BZOJ2281][SDOI2011]黑白棋(K-Nim博弈)相关推荐

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

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

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

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

  3. bzoj 2281: [Sdoi2011]黑白棋 bzoj 4550: 小奇的博弈(Nimk博弈+DP)

    4550: 小奇的博弈 Time Limit: 2 Sec  Memory Limit: 256 MB Submit: 68  Solved: 42 [Submit][Status][Discuss] ...

  4. 【bzoj2281】[Sdoi2011]黑白棋

    博弈论---Nimk问题. dp再搞搞. 很容易看出,该游戏的终态是每两个棋子都紧靠着.当一颗棋子移动,另一方与该棋子对应的那一刻可以立即追上,使得仍旧紧靠,最终棋子动弹不得,游戏结束. 还能看出,对 ...

  5. MFC随机博弈黑白棋

    随机博弈黑白棋 随机博弈黑白棋 TxyITxs | 随机博弈黑白棋 | 2019.04.21 摘要 通过随机落子,实现黑白棋的博弈.无任何落子规则,棋子死活与围棋中棋子的死活一致,即存在至少一口气.动 ...

  6. 吴昊品游戏核心算法 Round 9 —— 正统黑白棋AI(博弈树)

    黑白棋程式简史 在1980年代,电脑并不普及,在黑白棋界里,最强的仍然是棋手(人类). 到了1990年代初,电脑的速度以几何级数增长,写出来的黑白棋程式虽然仍然有点笨拙,但由于计算深度(电脑的速度快) ...

  7. 人工智能导论实验2——野人渡河黑白棋问题

    人工智能导论实验2--野人渡河&黑白棋问题 实验目的及要求: 本项目要求能够理解人工智能的基本原理,理解状态空间的概念.原理和方法,掌握用状态空间表示问题的步骤,掌握搜索方法的基本原理,并能够 ...

  8. P7589 黑白棋(2021 CoE-II B

    原题P7589 黑白棋(2021 CoE-II B) 题目描述 \text{Alice}Alice 和 \text{Bob}Bob 正在玩一种称为"黑白棋"的游戏.该游戏的规则如下 ...

  9. C++程设实验项目三:黑白棋与基于UCT算法的AI

    在这篇博客里,我将总结一下在这次实验中学到的UCT算法实现原理. 首先是参考文章: https://blog.csdn.net/u014397729/article/details/27366363 ...

最新文章

  1. 全面感知通用目标:建模、分割和重建(CVPR2021)
  2. thrift - C#(CSharp)客户端连接池(ConnectionPool)
  3. 使用openpyxl去操作Excel表格
  4. Nginx安装,Nginx静态缓存,Nginx Gzip压缩,Nginx负载均衡,Nginx方向代理,Nginx+Tomcat+Redis做session共享
  5. Gradle:我们需要另一个构建工具吗?
  6. x-lite for linux,Linux Lite 4.6正式发布:现基于Ubuntu 18.04.3 LTS
  7. cpu开机就是60℃_注意,制冷机组开机前这些检查很重要
  8. 开源框架_Index
  9. 硬盘安装 Ubuntu 9.04 与 XP 双系统 (含 Grub 不写入 MBR 的方法)
  10. 第七章_生成对抗网络(GAN)
  11. Unity打包WebGL遇到的il2cpp.exe did not run properly问题
  12. 向量设计丨导师简介丨客户案例丨商业活动丨跨界合作
  13. PCB十六大可靠性测试,看看您的板是否经得起测试?
  14. 【VBA研究】关于工作表单元格复制粘贴的语句
  15. 拓嘉启远:拼多多购物运输中的商品能拒收吗
  16. 心理压力的测试软件,心理压力测量量表(WYB)
  17. oracle里有没有stuff,STUFF函數在SQL Server和ORACLE中
  18. 揭开中本聪的真实身份?这只是杀毒软件之父疯狂人生中的一件小事
  19. AtCoder题解 —— AtCoder Beginner Contest 182 —— D - Wandering
  20. python的list合并

热门文章

  1. 远程协助——帮助你解决电脑问题
  2. 微信小程序开发入门教程(十一)
  3. matlab 0106,MATLAB控制系统仿真与实例详解.pdf
  4. 单项目多JDBC驱动版本加载
  5. 牛客寒假算法基础集训营6 I-wzoi
  6. python2G expanding 的用法, 最大回撤
  7. 2019运营商最新号码段正则表达式
  8. OBS录制视频,如何隐藏鼠标
  9. [2022-09-20]神经网络与深度学习第2章-simple classification
  10. ffmpeg转码时对变帧率和固定帧率的处理