洛谷P6218 [USACO06NOV] Round Numbers S

这个题是数位dp,dp[i][j][h]表示到第i为有h个0,j=1小于0等于,可以求出答案。

#include<stdio.h>
int dp[41][2][41];//kge1
int a[41],lena;
void init(){
    dp[1][1][1]=dp[1][0][0]=1;
    for(int i=2;i<=40;i++){
        for(int j=0;j<=i;j++){
            if(j!=0)dp[i][1][j]+=dp[i-1][1][j-1]+dp[i-1][0][j-1];
            dp[i][0][j]+=dp[i-1][1][j]+dp[i-1][0][j];
        }
    }
//    for(int i=1;i<=5;i++)
//        for(int j=0;j<=i;j++){
    //        printf("%d %d %d %d
",i,j,dp[i][0][j],dp[i][1][j]);
//        }
        
        
}
int work(int x){
//    printf("---%d
",x);
    lena=0;
    int anss=0;
    while(x){
        a[++lena]=x%2;
        x/=2;
    }
    for(int i=1;i<lena;i++){
        for(int j=0;j<=i/2;j++)anss+=dp[i][1][j];
    }
//    printf("%d
",anss);
    int add=1;
    for(int i=lena-1;i>0;i--){
        if(a[i]==1){
            for(int j=0;j+add<=(lena)/2;j++)anss+=dp[i][0][j];
            add++;
        }
    }
//    printf("%d
",anss);
    return anss;
}
int main(){
    int p,q;init();
    scanf("%d%d",&p,&q);
    printf("%d",(work(q+1)-work(p)));
    return 0;
}

    
原文地址:https://www.cnblogs.com/sy666/p/13586956.html