题目:

Round Numbers
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 8492   Accepted: 2963

Description

The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro, Sham, Bo', and a host of other names) in order to make arbitrary decisions such as who gets to be milked first.
They can't even flip a coin because it's so hard to toss using hooves.

They have thus resorted to "round number" matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both "round numbers", the first cow wins,

otherwise the second cow wins.

A positive integer N is said to be a "round number" if the binary representation of N has as many or more zeroes than it has ones. For example, the integer 9, when written in binary form, is 1001. 1001 has two zeroes and two ones; thus,
9 is a round number. The integer 26 is 11010 in binary; since it has two zeroes and three ones, it is not a round number.

Obviously, it takes cows a while to convert numbers to binary, so the winner takes a while to determine. Bessie wants to cheat and thinks she can do that if she knows how many "round numbers" are in a given range.

Help her by writing a program that tells how many round numbers appear in the inclusive range given by the input (1 ≤ Start < Finish ≤ 2,000,000,000).

Input

Line 1: Two space-separated integers, respectively Start and Finish.

Output

Line 1: A single integer that is the count of round numbers in the inclusive range Start..Finish

Sample Input

2 12

Sample Output

6

思路基本上和网上http://zhyu.me/acm/poj-3252.html做的非常类似:

举例说明,

[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,结果相加(因为前缀不一样。所以后面无论怎么组合都是唯一的)





将第一部分和第二部分的结果相加。就是最后的结果了。

唯一特别须要注意的是在计算组合数的时候非常easy越界。尽管上面分析了计算结果在int范围内是没有问题的,可是计算组合数中间过程还是非常可能越界,所以这里要特别注意。

解决方法是利用C(n,m)=C(n-1,m-1)+C(n-1,m)进行递归计算,而不是使用传统的乘法计算方式。为了更有效率一点,能够事先计算好n=1~32,m=1~32的组合数的结果然后存起来。

import java.util.*;

public class Combinatorics_RoundNumbers3252 {

	/**
* @param args
*/
public static void main(String[] args) { Scanner in=new Scanner(System.in);
Init();
while(in.hasNext())
{
int a=in.nextInt();
int b=in.nextInt();
//System.out.println(roundNumber(a-1)+" " +roundNumber(b));
System.out.println(roundNumber(b)-roundNumber(a-1));
} } static int c[][]=new int[35][35];
public static void Init(){
for(int i=0;i<33;i++){
c[i][0]=c[i][i]=1;
for(int j=1;j<i;j++)
c[i][j]=c[i-1][j]+c[i-1][j-1];
} } public static int roundNumber(int value)
{
char b[]=toBinary(value);
int sum=0;
for(int len=1;len<b.length;len++)
{
for(int j=(len+1)/2;j<len;j++)
sum+=c[len-1][j];
}
int zeros=0;
for(int i=1;i<b.length;i++)
{
if(b[i]=='1')
{
int k=(b.length+1)/2;
int m=Math.max(0, k-(zeros+1));
int n=b.length-i-1;
for(int j=n;j>=m;j--)
sum+=c[n][j];
}
else
{
zeros++;
}
}
if(2*zeros>=b.length)
sum++;
return sum;
} private static char[] toBinary(int value) {
return Integer.toBinaryString(value).toCharArray();
} /*public static int roundNumberOfLength(int len)
{
int k=len/2;
if(len%2==0)
{
return (1<<(len-2));
}
else
{
return ((1<<(len-1))-choose(len-1,k))/2;
}
}*/ public static int choose(int n, int m) { if(n==0)
return 0;
if(m==0||m==n)
return 1;
if(m>n)
return 0;
return choose(n-1,m-1)+choose(n-1,m);
} }

poj3252-Round Number 组合数学的更多相关文章

  1. POJ3252——Round Number(组合数学)

    Round Numbers DescriptionThe cows, as you know, have no fingers or thumbs and thus are unable to pla ...

  2. [BZOJ1662][POJ3252]Round Numbers

    [POJ3252]Round Numbers 试题描述 The cows, as you know, have no fingers or thumbs and thus are unable to ...

  3. [poj3252]Round Numbers_数位dp

    Round Numbers poj3252 题目大意:求一段区间内Round Numbers的个数. 注释:如果一个数的二进制表示中0的个数不少于1的个数,我们就说这个数是Round Number.给 ...

  4. POJ 3252 Round Numbers 组合数学

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

  5. Round Numbers(组合数学)

    Round Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10484 Accepted: 3831 Descri ...

  6. poj3252 Round Numbers

    Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7625   Accepted: 2625 Des ...

  7. POJ 3252 Round Number(数位DP)

    Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6983   Accepted: 2384 Des ...

  8. POJ3252 Round Numbers —— 数位DP

    题目链接:http://poj.org/problem?id=3252 Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Su ...

  9. poj3252 Round Numbers(数位dp)

    题目传送门 Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16439   Accepted: 6 ...

随机推荐

  1. Python 3 实现数字转换成Excel列名(10进制到26进制的转换函数)

    背景: 最近在看一些Python爬虫的相关知识,讲爬取的一些数据写入到Excel表中,当时当列的数目不确定的情况下,如何通过遍历的方式讲爬取的数据写入到Excel中. 开发环境: Python 3  ...

  2. CSDN开博一周年--总结、感想和未来规划

    2012年9月22日,我在CSDN发表了第1篇博文-为了忘却的纪念,我的天龙游戏生涯.本文讲述了我大学期间玩网络游戏-天龙八部的故事. 在大学期间,实际上我也有自己的帐号-huoyingfans,主要 ...

  3. jsonp实现原理

    jquery 封装在 ajax方法 里面的jsonp jsonp跨域的原理       1:使用script 标签发送请求,这个标签支持跨域访问       2:在script 标签里面给服务器端传递 ...

  4. ZOJ 3288 Domination

    D - Domination Time Limit:8000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Descr ...

  5. org.apache.hadoop.ipc.Client: Retrying connect to server

    这个问题导致jps查看结点进程时发现找不到NodeManager或一段时间后消失,网上查找了很多博客,因hadoop版本不一样且出错的原因也可能不同,所以找了老半天. 步骤:jps --> 看l ...

  6. HDU 3240

    求卡特兰数前N项的和模M. 直接求必定是不可能的,卡特兰数太大了.想了好久,本打算把位数拆成素数相乘,然后记录下各素数的个数计算.可惜,TLE....因为N太大了. 除法必定是要用到逆元的,但分母与M ...

  7. HDU 1023

    卡特兰数.把进栈看成是+1,出栈看成是-1,任何时候部分和都有a1+a2+....ak>=0.求这样的数列的个数.这明显是卡特兰数的一个解释嘛.在<组合数学>这本书就有这样的原本的证 ...

  8. Android实现天气预报温度/气温折线趋势图

     Android实现天气预报温度/气温折线趋势图 天气预报的APP应用中,难免会遇到绘制天气温度/气温,等关于数据趋势的折线或者曲线图,这类关于气温/温度的折线图,通常会有两条线.一条是高温线,一 ...

  9. 设计模式入门之代理模式Proxy

    //代理模式定义:为其它对象提供一种代理以控制对这个对象的訪问 //实例:鉴于书中给出的样例不太好.并且有些疑问,所以直接用保护代理作为实例 //要求,一旦订单被创建,仅仅有订单的创建人才干够改动订单 ...

  10. Double 与 Float 的值的比較结果

    首先看geeksforgeeks上的两个程序: 程序1: #include<stdio.h> int main() { float x = 0.1; if (x == 0.1) print ...