以sample为例子
 [2,12]区间的RoundNumbers(简称RN)个数:Rn[2,12]=Rn[0,12]-Rn[0,1]
 即:Rn[start,finish]=Rn[0,finish]-Rn[0,start-1]
 所以关键是给定一个X,求出Rn[0,X]
 现在假设X=10100100 
 这个X的二进制总共是8位,任何一个小于8位的二进制都小于X
 第一部分,求出长度为[0,7]区间内的二进制是RoundNumber的个数
  对于一个长度为Len的二进制(最高位为1),如何求出他的RoundNumbers呢(假设为用R(len)来表达),分为奇数和偶数两种情况
  1、奇数情况:在Len=2k+1的情况下,最高位为1,剩下2k位,至少需要k+1为0
   用C(m,n)表示排列组合数:从m个位置选出n个位置的方法
   R(len)=C(2k,k+1)+C(2k,k+2)+...+C(2k,2k).
   由于 A:C(2k,0)+C(2k,1)+...+C(2k,2k)=2^(2k)
     B:C(2k,0)=C(2k,2k), C(2k,1)=C(2k,2k-1) ,,C(2k,i)=C(2k,2k-i)
   于是  C(2k,0)+C(2k,1)+...+C(2k,2k)
    = C(2k,0)+C(2k,1)+...+C(2k,k)+C(2k,k+1)+C(2k,K+2)+...+C(2k,2k)
    = 2*R(len)+C(2k,k)
    =2^(2k)
    所以R(len)=1/2*{2^(2k)-C(2k,k)};
  2. 偶数情况 len=2*k,类似可以推到 R(len)=1/2*(2^(2k-1));
 第二部分,对于上面这个长度为8的例子:即X=10100100,首先如果本身是RoundNumbers,第二部分的结果总数+1
  第一部分已经将长度小于8的部分求出。现在要求长度=8的RoundNumber数目
  长度为8,所以第一个1不可改变
  现在到第二个1,如果Y是前缀如100*****的二进制,这个前缀下,后面取0和1必然小于X,已经有2个0,一个1,剩下的5个数字中至少需要2个0,
   所以把第二个1改为0:可以有C(5,2)+C(5,3)+C(5,4)+C(5,5)
  现在第三个1,也就是前最为101000**,同样求出,至少需要0个0就可,所以有C(2,0)+C(2,1)+C(2,2)个RoundNumbers
  。。。
  将所有除了第一个1以外的1全部变为0,如上算出有多少个RoundNumbers,结果相加(由于前缀不一样,所以后面不管怎么组合都是唯一的)

将第一部分和第二部分的结果相加,就是最后的结果了。
 精度要求方面,用int就可以了:two billion=20亿<2*1024*1024*1024=2^31,需用31位来表示数组,由于第一位总是1,所以求组合数的时候最多求30,C(30,k),k取值区间是[0,30],因为C(k,i)<2^k,所以结果用int表示就可以

Problem: 3252  User: ycdoit
Memory: 148K  Time: 0MS
Language: C++  Result: Accepted
#include<iostream>
using namespace std;
const int MS=31;
int C[MS][MS];        //[0,...30]
int power2[MS];        //1 2 4 8 ... 2^(MS-1)
int Binary[MS];
int Solve(int X){
    if(X<=1)    return 0;
    int i,j,k,n0,n1,Len,res=0;
    for(i=0;i<MS;++i)    Binary[i]=((power2[i]&X)!=0)?1:0;
    for(i=MS-1;i>=0 && Binary[i]==0;--i);    //停止的时候,i指向1        //总长度为i+1
    for(Len=i;Len>=1;--Len){        //求出 [1...i]的R(len)
        if(Len%2==1)    res+=(( power2[Len-1]-C[Len-1][(Len-1)/2])>>1);
        else    res+=(power2[Len-1]>>1);
    }
    for(j=i,n0=0,n1=0;j>=0;--j)    if(Binary[j])    ++n1;    else ++n0;
    if(n1<=n0)    ++res;
    for(j=i-1,n0=0,n1=1;j>=0;--j)    {
        if(Binary[j]){    //后面还有j位    第j位临时当做0
            for(k=j;k>=0 && k+n0+1>=j-k+n1;--k)        res+=C[j][k];
            ++n1;
        }
        else ++n0;
    }
    return res;
}
int main(){
    int i,j,Start,Finish;
    for(i=0;i<MS;++i)    C[i][0]=1,C[i][i]=1,power2[i]=(1<<i);
    for(i=2;i<MS;++i)    for(j=1;j<i;++j)    C[i][j]=C[i-1][j-1]+C[i-1][j];
    scanf("%d%d",&Start,&Finish);
    printf("%d\n",Solve(Finish)-Solve(Start-1));
    return 0;
}

poj 3252 Round Numbers 【推导·排列组合】的更多相关文章

  1. POJ 3252 Round Numbers(组合)

    题目链接:http://poj.org/problem?id=3252 题意: 一个数的二进制表示中0的个数大于等于1的个数则称作Round Numbers.求区间[L,R]内的 Round Numb ...

  2. [ACM] POJ 3252 Round Numbers (的范围内的二元0数大于或等于1数的数目,组合)

    Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8590   Accepted: 3003 Des ...

  3. Round Numbers (排列组合)

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7558   Accepted: 2596 Description The c ...

  4. POJ 3252 Round Numbers 组合数学

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13381   Accepted: 5208 Description The ...

  5. POJ 3252 Round Numbers

     组合数学...(每做一题都是这么艰难) Round Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7607 A ...

  6. poj 3252 Round Numbers(数位dp 处理前导零)

    Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...

  7. POJ 3252 Round Numbers 数学题解

    Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...

  8. POJ 3252 Round Numbers(组合数学)

    Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10223   Accepted: 3726 De ...

  9. POJ 3252 Round Numbers(数位dp&amp;记忆化搜索)

    题目链接:[kuangbin带你飞]专题十五 数位DP E - Round Numbers 题意 给定区间.求转化为二进制后当中0比1多或相等的数字的个数. 思路 将数字转化为二进制进行数位dp,由于 ...

  10. POJ - 3252 - Round Numbers(数位DP)

    链接: https://vjudge.net/problem/POJ-3252 题意: The cows, as you know, have no fingers or thumbs and thu ...

随机推荐

  1. 修改 myeclipse8.5 servlet 模板

    在myeclipse8.5的安装目录下找到 \Common\plugins下的com.genuitec.eclipse.wizards_8.5.0.zmyeclipse75020090612.jar ...

  2. boost::bind 和 boost::function 基本用法

    这是一篇介绍bind和function用法的文章,起因是近来读陈硕的文章,提到用bind和function替代继承,于是就熟悉了下bind和function的用法,都是一些网上都有的知识,记录一下,期 ...

  3. keil中编译时出现*** ERROR L107: ADDRESS SPACE OVERFLOW

    解决方法: http://zhidao.baidu.com/link?url=DWTVVdALVqPtUt0sWPURD6c1eEppyu9CXocLTeRZlZlhwHOA1P1xdesqmUQNw ...

  4. bat定时执行,清除PHP缓存

    bat中需要设置一个等待时间,执行完一条命令后,等待30分钟后在执行第二条命令,请问怎么做?急急急----谢谢大家 @echo off& echo wscript.sleep wscript. ...

  5. Unity3D音乐音效学习笔记

    对于Unity3D的音乐音效这块一直没有好好的看过,现在准备好好的研究一下,并作为一个笔记记录下. 支持格式 在游戏中,一般存在两种音乐,一种是时间较长的背景音乐,一种是时间较短的音效(比如按钮点击, ...

  6. MFC实现数独(1)

    雨天纷纷扰扰,数月里每日有雨,这个夏天不热,写这个数独的动机很简单:实践是最好的成长方式,想要获得自信,必有这么一遭,我躲不过.至于决定记录成博客,则是因为很久没有写文章,经常感觉脑海里很空白,屡次开 ...

  7. pygame “音乐盒”---- 播放一首歌& 点击对话框后背景以及对话框大小改变

    有时,你用pygame写的游戏也许需要播放一些背景音乐,该怎么做呢,直接上代码: 下面的代码,有关于: 1>设置对话框图标.大小.标题 2>播放音乐 3>设置背景图片,以及获取背景图 ...

  8. skyline TerraExplorer fly设置相对路径的方法

    软件环境:TerraExplorer Pro(以下简称TEP)6.5 在TEP中,对于本地(非网络)文件路径,默认都是绝对路径,在移动数据时非常麻烦,以下是本人总结出一些设置相对路径的规则 假设fly ...

  9. Android EditText载入HTML内容(内容包括网络图片)

    android中的Html.fromHtml能够用来载入HTML的内容.fromHtml有三个參数须要设置,第一个是要显示的html内容,第二个就是要说的重点,ImageGetter,用来处理图片载入 ...

  10. 基础数据结构 之 队列(python实现)

    队也是编程开发中常见的一种数据结构.栈和队可用来模拟函数的递归过程.队的特点为先入先出,主要操作包括入队和出队.入队时需判断队是否已满,出队时需判断队是否为空.下面给出一个队的python实现的例子: ...