POJ Round Numbers(数位DP)

题目大意:

Round Number:  将一个整数转化为二进制数字后,(不含前导0) 要是0的个数 大于等于1的个数 则是 Round Number

问从L-R之中有多少个Round Number

题目分析:

要转化为2进制数字,我们用10进制保存明显不好判断0和1的个数,所以选择用8进制来存储,这样的话每一次进位会多出 ”000“, 然后再加上8进制的尾数, 最后我们可以得出增加了几个 1 和 增加了 几个 0

需要注意的一点就是, 当前面的数字小于 8 的时候 我们要对 前导 0 进行特殊判断

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

#include<cmath>

using namespace std;

typedef __int64 LL;

LL dp[20][163][133];//dp[位数][0的个数][1的个数]

int bit[50];

int binary[8][2] = { {3,0}, {2,1},{2,1},{1,2},{2,1},{1,2},{1,2},{0,3} };

LL dfs(int pos,int preCou0,int preCou1,int flag,int len)

{

    if(pos == -1)

    {

        return  (preCou1 || preCou0) && preCou0 >= preCou1;//这里要对 0 进行特殊判断, 将0去掉

    }



    if( !flag && dp[pos][preCou0][preCou1] != -1)

        return dp[pos][preCou0][preCou1];



    LL ans = 0;

    int end = flag?bit[pos]:7;



    for(int i=0; i<= end; i++)

    {

        int nowCou0 = preCou0 + binary[i][0];

        int nowCou1 = preCou1 + binary[i][1];

        if(preCou0 == 0 && preCou1 == 0)//判断是否是第一位,若是第一位则需要进行特殊处理

        {

            if(i == 0 || i == 1)nowCou0 = 0;

            if(i == 2)nowCou0 = 1;

            if(i == 3)nowCou0 = 0;

        }



        ans += dfs(pos-1, nowCou0, nowCou1, flag && i == end, len);

    }

    if(!flag)

        dp[pos][preCou0][preCou1] = ans;



    return ans;

}





LL solve(LL n)

{

    int len = 0;



    while(n)

    {

        bit[len++] = n%8;

        n /= 8;

    }

    

    return dfs(len-1, 0, 0, 1, len-1);

}



int main()

{

    LL a, b;

    

    memset(dp, -1 ,sizeof(dp));

    while(scanf("%I64d%I64d", &a, &b) != EOF)

    {

    //    printf("%I64d\n", solve(a));

    //    printf("%I64d\n", solve(b));

        printf("%I64d\n", solve(b) - solve(a-1) );

    }

    return 0;

}



/*



0的个数 大于等于 1的个数

1    0001

2    0010   1

3    0011

4    0100   1

5    0101

6    0110 

7    0111

8    1000   1

9    1001   1

10   1010   1

11   1011

12   1100   1

13   1101   

14   1110

15   1111

16   10000  1



*/

 

你可能感兴趣的:(number)