poj 3252 Round Numbers

题目链接:http://poj.org/problem?id=3252

题意:给出一个二进制区间,求出0的个数不小于1的个数这样的二进制个数

解法:数位DP,定义状态dp[len][num_zero][num_one],num_zero 定义为写0的个数。

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<cstdlib>

 5 #include<cmath>

 6 #include<algorithm>

 7 #define inf 0x7fffffff

 8 #define exp 1e-10

 9 #define PI 3.141592654

10 using namespace std;

11 typedef long long LL;

12 LL digit[35];

13 LL dp[35][35][35];

14 LL dfs(LL len,LL num_zero,LL num_one,bool fp,int flag)

15 {

16     if (!len)

17     {

18         if (flag && num_zero>=num_one) return 1;

19         return 0;

20     }

21     if (!fp && dp[len][num_zero][num_one]!=-1)

22     return dp[len][num_zero][num_one];

23     LL ret=0;

24     LL fpmax= fp ? digit[len] : 1;

25     for (LL i=0 ;i<=fpmax ;i++)

26     {

27         LL s= i==1 ? 1 : 0;

28         LL s2= flag && i==0 ? 1 : 0;

29         ret += dfs(len-1,num_zero+s2,num_one+s,fp && i==fpmax,flag || i==1);

30     }

31     if (!fp) return dp[len][num_zero][num_one]=ret;

32     return ret;

33 }

34 LL f(LL n)

35 {

36     LL len=0;

37     while (n)

38     {

39         digit[++len]=n%2;

40         n /= 2;

41     }

42     return dfs(len,0,0,true,0);

43 }

44 int main()

45 {

46     LL a,b;

47     while (cin>>a>>b)

48     {

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

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

51     }

52     return 0;

53 }

 

你可能感兴趣的:(number)