poj 3252 Round Numbers

本文介绍了一种解决特定二进制区间内0的个数不小于1的个数的问题的数位动态规划(DP)方法,并提供了完整的C++实现代码。

题目链接: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 }

 

转载于:https://www.cnblogs.com/huangxf/p/3762978.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值