【洛谷5363】[SDOI2019] 移动金币(动态规划)
大致题意: 有\(n\)个格子,让你摆放\(m\)个金币。二人博弈,每次选择一个金币向左移任意格,无法移动者输。问有多少种方案使先手必胜。
阶梯\(Nim\)
阶梯\(Nim\)的基本模型,就是有\(n\)层楼梯(从\(0\sim n-1\)编号),每层楼梯上有若干石子,每次可以取任一层楼梯上任意多个石子到下一层,无法移动者输。
它的解决方法就是,去掉所有编号为偶数的楼梯,然后对剩下的这些编号为奇数的楼梯当成普通\(Nim\)来做。
原理是,如果一人移动编号为偶数的楼梯上的石子到下一层,如移动第\(2n\)层的\(a\)个石子到第\(2n-1\)层,那么无论何时对方都可以把这\(a\)个石子接着从第\(2n-1\)层移动到第\(2n-2\)层,因为\(2n-2\)层是必然存在的。
所以,移动偶数层的石子相当于是无效的,就可以直接忽略。
此题转化
对于这道题,我们可以发现,如果把每两个金币之间的空格当作一堆石子,这就是一个典型的阶梯\(Nim\)。
也就是说,若要先手必胜,就要满足奇数堆石子个数异或值不为\(0\)。
这显然不好求,所以我们可以转而求异或值为\(0\)的方案数,再用总方案数\(C_n^m\)减去它即为答案。
动态规划
考虑如何求异或值为\(0\)的方案数。
可以在二进制下逐位\(DP\)。
我们设\(f_{i,j}\)表示满足二进制下从最高位至右数第\(i\)位异或值为\(0\),剩余石子总数为\(j\)的方案数。
那么对于\(f_{i,j}\)的转移,我们可以枚举有\(k\)个奇数堆石子个数二进制下第\(i\)位为\(1\),其中因为要使异或值为\(0\),因此\(k\)为偶数。
转移方程为:
\]
其中\(t1\)表示奇数堆的个数。
计算答案
我们可以枚举满足所有奇数堆每一位异或值为\(0\)时所剩的石子个数\(i\),这就是偶数堆的石子个数。
则用插板法就可以求出异或值为\(0\)的方案数为:
\]
其中\(t0\)表示偶数堆的个数。
最后用\(C_n^m\)减去这一方案数就是答案。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 150000
#define M 50
#define LN 20
#define X 1000000009
#define Qinv(x) Qpow(x,X-2)
#define C(x,y) (1LL*Fac[x]*IFac[y]%X*IFac[(x)-(y)]%X)//组合数
using namespace std;
int n,m,Fac[N+5],IFac[N+5],f[LN+5][N+5];
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
int main()
{
RI i,j,k,t0,t1,res=0;scanf("%d%d",&n,&m),t0=(m>>1)+1,t1=m+1>>1;//计算偶数堆和奇数堆个数
for(k=max(n,2*m),Fac[0]=i=1;i<=k;++i) Fac[i]=1LL*Fac[i-1]*i%X;//初始化阶乘
for(IFac[k]=Qinv(Fac[k]),i=k-1;~i;--i) IFac[i]=1LL*IFac[i+1]*(i+1)%X;//初始化阶乘逆元
for(f[LN][n-m]=1,i=LN-1;~i;--i) for(j=0;j<=n-m;++j)//动态规划
for(k=0;k<=t1&&j+(k<<i)<=n-m;k+=2) f[i][j]=(C(t1,k)*f[i+1][j+(k<<i)]+f[i][j])%X;
for(i=0;i<=n-m;++i) res=(C(i+t0-1,t0-1)*f[0][i]+res)%X;//计算异或值为0的方案数
return printf("%d",(C(n,m)-res+X)%X),0;//输出答案
}
【洛谷5363】[SDOI2019] 移动金币(动态规划)的更多相关文章
- BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...
- 随手练——洛谷-P1002 过河卒(动态规划入门)
题目链接:https://www.luogu.org/problemnew/show/P1002 题目还算良心,提醒了结果可能很大,确实爆了int范围, 这是一开始写的版本,用递归做的,先给地图做标记 ...
- 【洛谷】P2694 接金币(排序)
题目描述 在二维坐标系里,有N个金币,编号0至N-1.初始时,第i个金币的坐标是(Xi,Yi).所有的金币每秒向下垂直下降一个单位高度,例如有个金币当前坐标是(xf, yf),那么t秒后金币所在的位置 ...
- 洛谷P1002 过河卒 题解 动态规划
题目链接:https://www.luogu.com.cn/problem/P1002 题目大意 棋盘上\(A\)点有一个过河卒,需要走到目标\(B\)点.卒行走的规则:可以向下.或者向右.同时在棋盘 ...
- 洛谷P5774,可爱的动态规划。
如此可爱的动态规划见过么? 相信各位都非常喜欢动态规划,那我就写一道可爱的动态规划的题解吧. 题目:https://www.luogu.com.cn/problem/P5774 题意: 题意“挺明白” ...
- 洛谷P1028.数的计算(动态规划)
题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n≤1000),然后对此自然数按照如下方法进行处理: 1.不作任何处理; 2.在它的左边加上一个自然数,但该自然 ...
- [洛谷P3878][TJOI2010]分金币
题目大意:把$n(n\leqslant30)$个数分成两组,两组个数最多相差$1$,求出两组元素差的绝对值最小使多少 题解:模拟退火 卡点:$\exp$中的两个数相减写反,导致$\exp(x)$中的$ ...
- [洛谷P5361][SDOI2019]热闹又尴尬的聚会:构造题
分析 构造方法 (截图自UOJ群) 可以使用std::set维护这个过程,不过据说可以做到\(O(n+m)\).. 正确性证明 题目中的要求等价于\((p+1)(q+1) > n\) 设每次找出 ...
- 洛谷P1002 过河卒(动态规划)
题目描述 棋盘上 AA 点有一个过河卒,需要走到目标 BB 点.卒行走的规则:可以向下.或者向右.同时在棋盘上 CC 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为 ...
随机推荐
- PHP命令执行漏洞初探
PHP命令执行漏洞初探 Mirror王宇阳 by PHP 命令执行 PHP提供如下函数用于执行外部应用程序:例如:system().shell_exec().exec().passthru() sys ...
- 2019/12/12学习内容摘要(Linux系统用户与用户组管理②)
5.命令 chfn 用于修改用户的finger (finger为 /etc/passwd 文件第五个字段中显示的信息) 三,用户密码管理 1.命令passwd 格式 passwd [username ...
- Self Service Password 密码策略
1.在活动目录中新建一个用户,并赋予域管理员权限:2.拷贝conf目录下的config.inc.php为config.inc.local.php:3.按自己的实际情况及要求修改config.inc.l ...
- Python目录教程集和资料分享
以下整理的是python的基础笔记,需要python视频资料或更多的请关注我的公众号! 查看内容点击链接: Python简介及安装 Python的3种执行方式 变量及变量计算和引用 if, elif, ...
- IT兄弟连 HTML5教程 HTML5表单 HTML表单设计1
表单是PHP程序中最常使用的收集站点访问者信息的数据输入界面.通过表单浏览器获取用户的输入数据,并传送给Web服务器的脚本程序中,以各种不同的方式进行处理.在表单中提供了多种输入方式,包括文本输入域. ...
- vuex动态引入store modules
主要解决的问题每次建一个module需要自己去主index.js里面去注册 为了偷懒,也为了避免团队开发时同时对index.js 进行修改引发冲突 所以在index.js中 动态的对子目录和模块进行注 ...
- slave_master_info和slave_relay_log_info中的Master_log_pos不一致
最近在研究mysql的主从,发现一个问题,我在主库做任何修改时,在从库中只有slave_relay_log_info中的Master_log_pos在变化,而slave_master_info中的Ma ...
- 查看Oracle被锁的表以及如何解锁
注意权限问题 1.查看是否有被锁的表: select b.owner,b.object_name,a.session_id,a.locked_modefrom v$locked_object a,db ...
- CentOS 7安装配置MySQL 5.7
概述 前文记录了在Windows系统中安装配置MySQL 5.7(前文连接:https://www.cnblogs.com/Dcl-Snow/p/10513925.html),由于安装部署大数据环境需 ...
- springboot进入html
话不多说,转载 https://blog.csdn.net/sinat_33889619/article/details/78339042 这个博客写的真好