poj 3252 数位dp(Round Number)
2015-09-07 16:40
399 查看
题意:输入两个十进制正整数a和b,求闭区间 [a ,b] 内有多少个Round number。所谓的Round Number就是把一个十进制数转换为一个无符号二进制数,若该二进制数中0的个数大于等于1的个数,则它就是一个Round Number。
思路:用dp来做:dp[i][j]表示二进制长度为 i 的数字含 j 个0的个数,比如dp[3][1] = 2(101和110)。做法就是先打表求出dp数组。然后求出a和b各有多少位,之后特判两边,中间直接求。拿样例来说:问10和1100之间的个数。先求出10~11之间的个数,再求出1000~1100之间的个数,然后求出长度为3的总个数。
思路:用dp来做:dp[i][j]表示二进制长度为 i 的数字含 j 个0的个数,比如dp[3][1] = 2(101和110)。做法就是先打表求出dp数组。然后求出a和b各有多少位,之后特判两边,中间直接求。拿样例来说:问10和1100之间的个数。先求出10~11之间的个数,再求出1000~1100之间的个数,然后求出长度为3的总个数。
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <cstdlib> using namespace std; #define clc(s,t) memset(s,t,sizeof(s)) #define N 36 int dp ,sum ; int a,b; void init(){ int i,j; dp[1][0] = 1; clc(sum, 0); for(i = 2;i<=31;i++){ dp[i][0] = 1; for(j = 1;j<i;j++){ dp[i][j] = dp[i-1][j-1]+dp[i-1][j]; if(j>=(i+1)/2) sum[i] += dp[i][j]; } } } int solve(int x,int d){ int i,j,num=0,res=0; res = sum[d]; num = (d+1)/2; for(i = d-1;i>0;i--){ if(0 == ((1<<(i-1))&x)){ for(j = num;j<i;j++) res -= dp[i][j]; num--; } } return res; } int main(){ int i,j,k,res=0; init(); scanf("%d %d",&a,&b); for(i = 30;i>=0;i--) if((1<<i)&a) break; if((a&(a-1))==0) res +=sum[i+1]; else res += sum[i+1]-solve(a-1,i+1); for(j = 30;j>=0;j--) if((1<<j)&b) break; for(k = i+2;k<=j;k++) res += sum[k]; res += solve(b,j+1); if(i == j) res -= sum[i+1]; printf("%d\n",res); }
相关文章推荐
- 用深度遍历dfs判断一个有向图是否有环
- 虚幻引擎3命令行参数
- swing 界面操作打开文件对话框
- 2015年终总结(二)
- hdu1025(nlogn的求非递减子序列)
- BZOJ 2456: mode 水题
- js 字符串日期 转成 Date
- COCI CONTEST #3 29.11.2014 HONI
- typedef int (* func)(int ,int ) 定义函数指针类型 的理解
- (四)linux下配置jenkins--构建一个自由风格的项目
- STM32串口第一个字节丢失问题的分析过程
- Java基础-Java生成MD5简单实例
- memcached缓存服务器
- android开发关联源码
- Android中ListView复用导致其他Item显示异常
- UVA 11210 Chinese Mahjong
- Java高效读取大文件
- JAVA端通过Oozie Client 启动Oozie任务
- container_of分析
- hdfs源码分析第二弹