poj 3252 Round Numbers 数位dp
2014-12-25 09:43
405 查看
题意:
给区间【a,b】,求【a,b】中二进制表示中0的个数大于等于1的个数的数的数量。
思路:
数位dp与分组(类)组合计数有异曲同工之妙。[0,10100)=[0,10000)+[10000,10100)=****+100**(*表示任意取),数位dp时要注意对10100,[0,10000)没有前导0,但在算[10000,10100)时用到的dp函数是包含前导0的,所以[0,10000)要另外计数。
代码:
给区间【a,b】,求【a,b】中二进制表示中0的个数大于等于1的个数的数的数量。
思路:
数位dp与分组(类)组合计数有异曲同工之妙。[0,10100)=[0,10000)+[10000,10100)=****+100**(*表示任意取),数位dp时要注意对10100,[0,10000)没有前导0,但在算[10000,10100)时用到的dp函数是包含前导0的,所以[0,10000)要另外计数。
代码:
//poj 3252 //sep9 #include <iostream> using namespace std; int dp[36][36]; void init() { dp[0][0]=1; dp[1][0]=1,dp[1][1]=1; for(int i=2;i<=31;++i){ dp[i][0]=1,dp[i][i]=1; for(int j=1;j<i;++j) dp[i][j]=dp[i-1][j]+dp[i-1][j-1]; } } int f(int x) { int i,j,tot=0,sum=0,flag=-1; for(i=31;i>0;--i){ if(x&(1<<i)){ if(flag==-1) flag=i; ++tot; if(tot>flag+1-tot) break; x=x^(1<<i); } if((1<<(i-1))<=x&&flag!=-1){ for(int k=0;k+tot<=flag+1-k-tot;++k) sum+=dp[i-1][k]; } } sum+=1; for(i=1;i<=flag;++i) for(j=0;j+1<=i-j-1;++j) sum+=dp[i-1][j]; return sum; } int main() { int a,b; init(); scanf("%d%d",&a,&b); printf("%d",f(b+1)-f(a)); return 0; }
相关文章推荐
- POJ 3252 Round Numbers(数位dp&记忆化搜索)
- POJ 3252 Round Numbers (数位DP)
- 【数位DP】POJ 3252 Round Numbers
- POJ 题目3252 Round Numbers(数位DP)
- POJ - 3252 Round Numbers 数位dp
- 【数位DP】【poj 3252】Round Numbers
- POJ - 3252 Round Numbers (数位dp&位运算)
- poj 3252 Round Numbers (数位DP)
- POJ 3252 Round Numbers(数位DP)
- POJ 3252 Round Numbers 数位dp
- poj 3252 Round Numbers(数位DP)
- poj 3252 Round Numbers(数位dp)
- POJ 3252 Round Numbers 数位DP
- POJ 3252 Round Numbers [数位DP]【动态规划】
- poj 3252 Round Numbers(数位DP)
- POJ 3252 - Round Numbers(数位dp)
- POJ 3252 Round Numbers (数位dp)
- poj 3252 Round Numbers 数位dp
- poj 3252 Round Numbers(数位DP,4级)
- POJ 3252 Round Numbers (数位DP)