Round Numbers就是一个表示成二进制的时候0比1多或者相等的正数,注意是正数,所以0就肯定不是了。
题目是给定一个区间,问在这个区间上的Round Numbers有多少个?
比如 N = 12, 则他的长度是4, 那么位数比4小的一定是比N小的Round Numbers
当len = 3 , 则 num = C(2,2) 因为此时第一位必须是1
同理 当len = 2. Num = C(1,1)
当 len = 3 num = 0则
当长度相同的时候
当 len = 4 此时round number 必须必1100小, 我们就从1入手, 当然了首位不能动
然后我们把以后的1一次变为0就可以保证 一定比N小, 当第二个1变为零时 即 前缀位10~的数, 又要满足条件 num = C(2,1) + C(2,2) 奏是这样
如果二进制N位数为奇数 设N = 2*k + 1, 则满足条件的比N -1位Round Numbers 是C(2K, K+1) ~ C(2K, 2K) 则
因为 C(N,0) + C(N, 1) + C(N,2) + ....+C(N,N) = 2^(N); && C(N, M) = C(N, N-M);
2^(2k) = C(2k,0)+C(2k,1)+...+C(2k,k-1) +C(2k,k)+C(2k,k+1)+C(2k,K+2)+...+C(2k,2k)
= C(2k,2k)+C(2k,2k-1)+...+C(2k,k+1) +C(2k,k)+C(2k,k+1)+C(2k,K+2)+...+C(2k,2k)
=2*num + C(2k,k);
Num = (2^(2k) - C(2k,k))/2;
同理 当N = 2*k 时 则满足条件的比N -1位Round Numbers 是C(2K-1, K) ~ C(2K,-1 2K-1)
2^(2k-1)=C(2k-1,0)+C(2k-1,1)+...+C(2k-1,k-1)+C(2k-1,k)+C(2k-1,K+1)+...+C(2k-1,2k-1)
=C(2k-1,2k-1)+C(2k-1,2k-2)+...+C(2k-1,k)+C(2k-1,k)+C(2k-1,K+1)+...+C(2k-1,2k-1)
=2*num
Num = 2^(2k-1)/2;
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int bit[33];
int dp[32][32];
void init()
{
memset(dp, 0, sizeof(dp));
//dp[i][j] 长度为 i, 包含 j 个 0 可以都为零
for( int i = 0; i <= 31; i++)
dp[i][0] = dp[i][i] = 1;
for(int i = 1; i <= 31; i++)
for(int j = 1; j < i; j++)
dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
return ;
}
void getbit( int x)
{
bit[0] = 0;
while(x)
{
bit[++bit[0]] = x % 2;
x/=2;
}
return ;
}
int solve(int n)
{
getbit(n);
int sum = 0;
//统计比n长度小的ROUND NUMBER (让第一位是1)
for(int i = 1; i < bit[0]; i++)
{//这时候就体现出来dp[i][j]为什么允许都是零了
for( int j = i - 1; 2*j >= i; j--)
sum += dp[i-1][j];
}
//统计跟n长度相等,值比n小的ROUNDE NUMBER
int znum = 0;
for( int i = bit[0] - 1 ; i >= 1; i--)
{
if(bit[i])
{