• 12.16省选模拟t1 黑白棋


    题意

    黑白棋

    另见SDOI2009黑白棋。

    分析

    发现因为题目限制,其本质可以变成取石子,也就是 \(num\) 游戏,并且是 \(k-nim\) 游戏。

    \(k-nim\) 游戏的获胜条件有结论:对所有数二进制分解,若每一位为1的数的个数都能被 \((k+1)\) 整除,则当前必败,否则必胜。

    题目问方案数,显然是可以dp的,同时很明显是按位dp,那么设状态 \(dp[i][j]\) 表示当前选了前 \(i\) 位,已经选了j个石子 的方案数。

    转移就是枚举当前这一位有多少堆石子取到1即可,具体见代码。

    代码

    luogu过了,OJ 90 .

    #include<bits/stdc++.h>
    using namespace std;
    //#ifdef ONLINE_JUDGE
    //  #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    //  char buf[1<<21],*p1=buf,*p2=buf;
    //#endif
    template<typename T>
    inline void read(T &x){
        x=0;bool f=false;char ch=getchar();
        while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
        while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
        x=f?-x:x;
        return ;
    }
    template<typename T>
    inline void write(T x){
        if(x<0) x=-x,putchar('-');
        if(x>9) write(x/10);
        putchar(x%10^48);
        return ;
    }
    #define ll long long
    #define ull unsigned long long
    #define ld long double
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define pc putchar
    #define PII pair<int,int>
    #define rep(i,x,y) for(register int i=(x);i<=(y);i++)
    #define dep(i,y,x) for(register int i=(y);i>=(x);i--)
    #define repg(i,x) for(int i=head[x];i;i=nex[i])
    #define filp(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define infilp(s) freopen(s".in","r",stdin)
    #define outfilp(s) freopen(s".out","w",stdout)
    const int MOD=1e9+7;
    inline int inc(int x,int y){x+=y;return x>=MOD?x-MOD:x;}
    inline int dec(int x,int y){x-=y;return x<0?x+MOD:x;}
    inline void incc(int &x,int y){x+=y;if(x>=MOD) x-=MOD;}
    inline void decc(int &x,int y){x-=y;if(x<0) x+=MOD;}
    inline void chkmin(int &x,int y){if(y<x) x=y;}
    inline void chkmax(int &x,int y){if(y>x) x=y;}
    const int N=1e5+5,M=205,INF=1e9+7;
    int n,K,d,Ans;
    int dp[18][N];//前i-1位的异或和为0,当前一共有j个石子
    int C[N][205];
    inline void Init(){
        C[0][0]=1;
        for(int i=1;i<=n;i++){
            C[i][0]=1;
            for(int j=1;j<=min(i,K);j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;
        }
        return ;
    }
    signed main(){
    //  double ST=clock();
        // ios::sync_with_stdio(false);
    //#ifndef ONLINE_JUDGE
    //  filp("my");
    //#endif
        read(n),read(K),read(d);Init();
        dp[0][0]=1;
        for(int i=1;i<=17;i++){
            for(int j=0;j<=n-K;j++){
                for(int k=0;k*(1<<(i-1))*(d+1)<=n-K&&k*(d+1)<=K/2;k++){
                    dp[i][j+k*(1<<(i-1))*(d+1)]=(dp[i][j+k*(1<<(i-1))*(d+1)]+1ll*dp[i-1][j]*C[K/2][k*(d+1)])%MOD;
                }
            }
        }
        for(int i=0;i<=n-K;i++) Ans=(Ans+1ll*dp[17][i]*C[n-i-K/2][K/2])%MOD;
        write((C[n][K]-Ans+MOD)%MOD);
    //  cerr<<"\nTime:"<<(clock()-ST)/CLOCKS_PER_SEC<<"s\n";
        return 0;
    }
    /*
     
    */
    
  • 相关阅读:
    从一个iOS毛头小子到现在的高级工程师, 我总结了一些经验,先跟大家分享一下一些好的资料
    iOS面试题---Objective_C语言特性:分类、扩展、代理、通知、KVO、KVC、属性
    200道iOS面试题面试题整理,底层、技术亮点公司需要的这里都有
    [iOS 开发] iOS 开发从菜鸟到高手?听听他们怎么说
    2020年面向iOS开发人员的知识点总结(更新中)
    OC项目转Swift指南
    来自老程序员的10条中肯建议
    面对职业瓶颈,iOS 开发人员应该如何突破?
    憨憨程序猿,不要让你的技术被简历埋没了
    总结:实现线程同步的八种方式
  • 原文地址:https://www.cnblogs.com/Akmaey/p/15728526.html
Copyright © 2020-2023  润新知