首页 > 其他分享 >[SDOI2019] 移动金币(阶梯博弈)

[SDOI2019] 移动金币(阶梯博弈)

时间:2024-01-29 12:12:09浏览次数:40  
标签:偶数 int 石子 阶梯 金币 SDOI2019 dp mod

题面

一枚金币向左移若干格等价若干个空格向右移一个金币,终状态为所有空格在最右,转换为阶梯博弈

阶梯博弈

每个阶梯上有若干枚石子,每次操作将同个阶梯的任意石子向下移一个阶梯,不能操作者输

等价对奇数阶梯做Nim博弈

先手按Nim博弈操作。若对方移动偶数阶梯,则将对方移动石子继续下移到偶数阶梯;否则按Nim博弈操作。

此时先手移动后奇数阶梯上无石子,对方移动偶数(>0)阶梯,先手继续下移到偶数(>=0)阶梯,直至对方无法操作。当奇数阶梯异或和不为0,先手必胜。

思路

题目等价将n-m个石子放入m+1个盒子,使得偶数(下标以1开始)盒子异或和为0的方案的补集。

异或和为0转换为二进制每一位1的个数为偶数,做计数dp

设\(dp_{i,j}\)为放入前i位1,剩下j个石子未放入的方案数

\[dp_{i,j} = \sum_{k\%2=0}^{\frac{m+1}{2}} dp_{i-1,j+2^{i-1}\times k}\times \begin{pmatrix} \frac{m+1}{2} \\k \\\end{pmatrix} \]

再将剩下的石子用插板法放入奇数盒

最后用总方案减去即为答案

代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int MAX=1.5e5+10,mod=1e9+9;
#define int long long
int n,m,dp[20][MAX],ans,f[MAX],inv[MAX];
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^'0');c=getchar();}
	return x;
}
inline int C(int n,int m){
    return f[n]*inv[m]%mod*inv[n-m]%mod;
}inline int power(int a,int b){
    int res=1;
    while(b){
        if(b&1)  res=res*a%mod;
        a=a*a%mod;b>>=1;
    }return res;
}
signed main(){ 
    n=read();m=read();
    f[0]=1;
    for(int i=1;i<=n;++i)  f[i]=f[i-1]*i%mod;
    inv[n]=power(f[n],mod-2);
    for(int i=n-1;i>=0;--i)  inv[i]=inv[i+1]*(i+1)%mod;
    dp[0][n-m]=1;int q=__lg(n-m)+1;
    for(int i=1,p=1;i<=q;++i,p<<=1)
        for(int j=0;j<=n-m;++j)
            for(int k=0;(k<=m+1>>1)&&(j+p*k<=n-m);k+=2)
                dp[i][j]=(dp[i-1][j+p*k]*C(m+1>>1,k)%mod+dp[i][j])%mod;
    for(int i=0;i<=n-m;++i)
        ans=(ans+dp[q][i]*C(i+(m>>1),m>>1)%mod)%mod;
    ans=(C(n,m)-ans+mod)%mod;
    printf("%lld",ans);
}

标签:偶数,int,石子,阶梯,金币,SDOI2019,dp,mod
From: https://www.cnblogs.com/yswn/p/17994223

相关文章

  • 2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有N堆金币, 第i堆金币
    2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有N堆金币,第i堆金币的总重量和总价值分别是m[i]、v[i],阿里巴巴有一个承重量为T的背包,但并不一定有办法将全部的金币都装进去,他想装走尽可能多价值的金币,所有金币都可以随意分割,分割完的金币重量价值比(也就是单位......
  • P5362 [SDOI2019] 连续子序列 题解--zhengjun
    题面传送门提供一种和其他题解完全不同的解法。记\(P_0\)为题中给出的序列,\(P_1\)为\(P_0\)取反的结果。记\(S_{l\simr}\)表示\(S_lS_{l+1}\dotsS_{r}\)。方便起见,\(P\)下标从\(0\)开始,其余的串都是从\(1\)开始。这里用\(P_{0,i}=\operatorname{popcount(i)}......
  • 洛谷 P5359 [SDOI2019] 染色
    洛谷传送门LOJ传送门dp好题。首先有一个显然的状态,设\(f_{i,x,y}\)为第\(i\)列上下两格的颜色分别为\(x,y\)的方案数。但是这样做时间复杂度至少为\(O(nm^2)\),无法接受。注意到全\(0\)列的转移是重复的。我们可以试着只在两个相邻非全\(0\)列转移。这样我们需......
  • 机甲战队国服无限金币ios版本
    机甲战队国服无限金币ios版本机甲战队国服无限金币ios版本机甲战队国服无限金币ios版本机甲战队国服无限金币ios版本机甲战队国服无限金币ios版本免费,专业刷金,进战队战队!!!!!!!!三天稳定1000金币,氪金党勿入,肝佬欢迎进入,目前国服金价一月免费肝1万金币,一起开黑刷金请进qq群947633......
  • PMP塔克曼阶梯模型
    塔克曼阶梯模型布鲁斯·塔克曼(BruceTuckman)的团队发展阶段(StagesofTeamDevelopment)模型可以被用来辨识团队构建与发展的关键性因素,并对团队的历史发展给以解释。团队发展的五个阶段是:组建期(Forming)、激荡期(Storming)、规范期(Norming)、执行期(Performing)和休整期(Adjourni......
  • 矩阵化为行阶梯型、行最简阶梯型、标准型、单位矩阵的方法
    1.行阶梯型1.1形式若有0行,都在下方从行上看,从左边起,出现连续的0的个数自上而下,严格单调增加1.2方法\[\left[\begin{matrix}1&-1&2&1&0\\2&-2&4&2&0\\3&0&6&-1&1\\0&3&0&0&1\end{matrix}\right]\]通过行变换将第一列尽量都变成0......
  • 【教3妹学编程-算法题】购买水果需要的最少金币数
    3妹:“你不是真正的快乐,你的笑只是你穿的保护色”2哥 :3妹还在唱五月天的歌啊,你不知道五月天假唱,现在全网都在骂呢。3妹:知道啊,可是关我什么事,这个歌的确好听啊。2哥 :嗯嗯,不错,还以为你是脑残粉,无论黑白都只管追星呢。3妹:我是只管追歌的,歌好听就行啦。2哥 :追哥?追哪个哥,难......
  • NOIP2015普及组金币
    NOIP2015普及组金币题目数据(n<=10000)根据题目要求与我们原来学过的打印数字三角形图形很相似。数字三角形如下,数字可以对应成天数:12 34  5  67  8  9  10每天加的金币就是行坐标即可:12  23  3  34  4  4  4代码如何:#includ......
  • QT实战 之翻金币游戏
    QT实战之翻金币游戏相较于原版的优化:关卡数据不是用静态的config配置,而是动态生成,每次打开的关卡都生成不同的游戏数据,增加了可玩性;关卡数据依据关卡等级的不同而生成不同难度的数据,随关卡的增加而不断提升难度;金币矩阵由原版的4*4升级为5*5,增加了游戏难度;选择关卡按钮使用......
  • 记录--实现金币飞入钱包的动画
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 效果金币从初始位置散开后逐个飞向指定位置,这是游戏中很常用的一个动画,效果如下:思路这个效果中,分成两个阶段:一定数量的金币从一个起点散开这些金币逐一飞向终点计算金币的初始散开位置生成圆周上的等......