zoukankan      html  css  js  c++  java
  • 求范围内【l,r] , 内二进制的零比一多的数

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int dp[37][73],a[37];
    inline int read()
    {
        register int ans=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
        return ans*f;
    }
    int dfs(int wi,int cha,bool lim,bool fir)      //枚举到哪一位,sum0-sum1,限制,是否有前导0
    {
        if(wi<1)
          return cha==32;
        if(!lim&&!fir&&dp[wi][cha]>-1)
          return dp[wi][cha];
        int o=lim? a[wi]:1;
        int ans=0;
        if(fir)
        {
            if(wi!=1)
              ans+=dfs(wi-1,cha,lim&&a[wi]==0,fir);
            else
              ans+=dfs(wi-1,cha-1,lim&&a[wi]==0,fir);
        }
        else
          ans+=dfs(wi-1,cha-1,lim&&a[wi]==0,fir);
        if(o>=1)
          ans+=dfs(wi-1,cha+1,lim&&a[wi]==1,0);         //a[wi]==1/0
        if(!lim&&!fir)
          dp[wi][cha]=ans;
        return ans;
    }
    int sol(int x)
    {
        int w=0,ans=0;
        while(x)
        {
            a[++w]=x&1;
            x/=2;
        }
        for(int i=0;i<=w;i++)
          ans+=dfs(w,i+32,1,1);
        return ans;
    }
    int main()
    {
        int s,f;
        s=read();f=read();
        for(int i=0;i<37;++i)
          for(int j=0;j<73;++j)
            dp[i][j]=-1;
        int a=sol(f);
        int b=sol(s-1);
        printf("%d
    ",a-b);
        return 0;
    }
    数位dp,dp[i][j]表示考虑到第i位(二进制位),剩下的位中0的个数与1的个数的差为j的数的个数。
    j可能为负,需要统一加上一个数(32吧)
    这道题需要考虑前导0,因为如果前面都是0的话,后面的0就不能算在里面
  • 相关阅读:
    HDOJ:1051
    新sort的用法
    python课堂整理14---函数式编程
    python课堂整理13---函数的作用域及匿名函数
    python课堂整理12---递归
    python课堂整理11---函数即变量
    python课堂整理10---局部变量与全局变量
    python课堂整理9---函数1
    python课堂整理8---字符串格式化
    python课堂整理7---集合
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9681266.html
Copyright © 2011-2022 走看看