首页 > 代码库 > poj 3252 Round Numbers

poj 3252 Round Numbers

/*调了半晚上了......感觉是凑出来的QAQ不过也还好思路比较清晰数位dp f[i]表示i位的二进制数中有几个合法的(默认开头一个是1)然后求[1,L] [1,R+1] 首先位数小的都行关键是位数一样的这里还要保证数值比他小比如 110100循环高位到低位 变成 10****统计****位的就好了这样就保证比他小 程序里那两个reverse啥的可以无视后期写的蒙蔽了 有点混乱 QAQ */#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int a,b,f[50][50];int Cal(int n,int m){    int r=1;    for(int i=1;i<=m;i++){        r*=(n-i+1);r/=i;    }    return r;}void Get(){    f[0][0]=1;    for(int i=1;i<=35;i++)        for(int j=0;j<=i;j++)            f[i][j]=Cal(i,j);}int sol(int x){    int data[35]={0},c[35]={0};    int r=0,len=0;    while(x){        data[++len]=x%2;x/=2;    }    memcpy(c,data,sizeof(data));    reverse(c+1,c+1+len);    for(int i=1;i<=len;i++)        c[i]=c[i-1]+c[i];    for(int i=1;i<len;i++)        for(int j=0;j<=i/2-1;j++)            r+=f[i-1][j];    reverse(c+1,c+1+len);    for(int i=len-1;i>=1;i--)if(data[i])        for(int j=0;j+c[i+1]<=len/2;j++)            r+=f[i-1][j];    return r;}int main(){    scanf("%d%d",&a,&b);Get();    printf("%d\n",sol(b+1)-sol(a));    return 0;}

 

poj 3252 Round Numbers