zoukankan      html  css  js  c++  java
  • 51Nod 1301 集合异或和 —— 异或DP

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1301

    参考博客:https://blog.csdn.net/qq_33229466/article/details/78418414

    原来是DP。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int const maxn=2005,mod=1e9+7;
    int n,m,w,bin[15];
    ll ans,f[3][2050][15];
    int get(int x){int ret=0; while(x)ret++,x>>=1; return ret;}
    void init()
    {
        bin[0]=1;
        for(int i=1;i<15;i++)bin[i]=(bin[i-1]<<1);
    }
    int main()
    {
        init();
        scanf("%d%d",&n,&m); w=get(max(n,m));
        for(int i=0,p,q;i<=w;i++)
        {
            memset(f,0,sizeof f);
            p=0; f[0][0][0]=1;
            int lim=0;
            for(int j=1;j<=max(n,m);j++)//枚举数 
            {
                p^=1; q=!p;
                if(j>=bin[lim])lim++;
    //            int tmp=(j&bin[i]); //j&bin[i]不仅是0或1!!!
                bool tmp=(j&bin[i]); 
                for(int s=0;s<bin[lim];s++)//<
                {
                    f[p][s][0]=f[q][s][0]; f[p][s][1]=f[q][s][1];
                    for(int k=0;k<=1;k++)
                    {
                        if(j<=m)(f[p][s][k]+=f[q][s^j][k^tmp])%=mod;//给B 
                        if(j<=n)(f[p][s][k]+=f[q][s^j][k])%=mod;//给A 
                    }
                }
            }
            for(int s=bin[i];s<bin[i+1];s++)ans=(ans+f[p][s][1])%mod;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Mayan游戏
    选择客栈
    Redundant Paths
    中心选址
    辗转相除
    字符串
    线段覆盖
    配置魔药
    宝库通道
    教官的监视
  • 原文地址:https://www.cnblogs.com/Zinn/p/9607038.html
Copyright © 2011-2022 走看看