poj 3252 Round Number 数位dp


Round Numbers

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 11481   Accepted: 4305

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

Source

USACO 2006 November Silver

[Submit]   [Go Back]   [Status]  
[Discuss]

Home Page   Go
Back
  To top

转化成二进制然后按位dp统计0和1的个数

注意判断是否是前导0

ACcode:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int dp[40][40][40];
int a,b;
int data[40];
int dfs(int len,int is_0,int is_1,int pre,int limit){
    if(!len)return is_0>=is_1;
    if(!pre&&!limit&&dp[len][is_0][is_1]!=-1)return dp[len][is_0][is_1];
    int ed=limit?data[len]:1;
    int ans=0;
    for(int i=0;i<=ed;++i){
        if(pre){
            if(i==0)ans+=dfs(len-1,0,0,1,limit&&i==ed);
            else ans+=dfs(len-1,is_0,is_1+1,0,limit&&i==ed);
        }
        else {
            if(i==0)ans+=dfs(len-1,is_0+1,is_1,0,limit&&i==ed);
            else ans+=dfs(len-1,is_0,is_1+1,0,limit&&i==ed);
        }
    }
    if(!limit&&!pre)dp[len][is_0][is_1]=ans;
    return ans;
}
int fun(int a){
    int len=0;
    while(a){
        data[++len]=a%2;
        a>>=1;
    }
    return dfs(len,0,0,1,1);
}
void doit(){
    printf("%d\n",fun(b)-fun(a-1));
}
int main(){
    memset(dp,-1,sizeof(dp));
    while(~scanf("%d%d",&a,&b))doit();
    return 0;
}
时间: 2024-08-28 08:29:17

poj 3252 Round Number 数位dp的相关文章

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

题目链接:[kuangbin带你飞]专题十五 数位DP E - Round Numbers 题意 给定区间.求转化为二进制后当中0比1多或相等的数字的个数. 思路 将数字转化为二进制进行数位dp,由于一个二进制数的最高位必须为1.所以设置变量first记录前面位是否有1,若有1,则可随意放,否则,仅仅可放1. 同一时候.上面的推断决定了搜索时len的大小与二进制本身的长度不一定相等,所以需两个变量对1和0的个数进行记录. 用dp[a][b][c]保存长度a,b个0,c个1的数字个数.记忆化搜索.

POJ 3252 Round Numbers (数位DP)

题意:求区间内一个数二进制位1的数量大于等于0的数的个数. 析:dp[i][j][k] 表示前 i 位,长度为 j 的,1的数量是 k.注意前导0. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <

POJ 3252 round numbers(数位DP)

#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <cstring> #include <set> #include <stack> #include <m

POJ 3252 Round Numbers 数位dp(入门

题目链接:点击打开链接 题意: 给定一个区间,求区间内有多少个合法数(当这个数的二进制中0的个数>=1的个数称为合法数 二进制无前导0) 思路: cnt[i]表示二进制长度为i位(即最高位为1,其他位任意)时的合法数个数. sum[i] 就是二进制长度<=i位的合法数个数. 然后从最高位枚举到低位即可.维护当前0的个数. #include <cstdio> #include <algorithm> #include <cstring> #include &l

POJ 3252 Round Numbers 数学题解

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

Hdu3079Balanced Number数位dp

枚举支点,然后就搞,记录之前的点的力矩和. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <s

poj 3252 Round Numbers 【推导&#183;排列组合】

以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),如何求出他的Rou

SPOJ MYQ10 Mirror Number 数位dp&#39;

题目链接:点击打开链接 MYQ10 - Mirror Number A number is called a Mirror number if on lateral inversion, it gives the same number i.e it looks the same in a mirror. For example 101 is a mirror number while 100 is not. Given two numbers a and b, find the number

多校5 HDU5787 K-wolf Number 数位DP

1 // 多校5 HDU5787 K-wolf Number 数位DP 2 // dp[pos][a][b][c][d][f] 当前在pos,前四个数分别是a b c d 3 // f 用作标记,当现在枚举的数小于之前的数时,就不用判断i与dig[pos]的大小 4 // 整体来说就,按位往后移动,每次添加后形成的数都小于之前的数,并且相邻k位不一样,一直深搜到cnt位 5 // http://blog.csdn.net/weizhuwyzc000/article/details/5209769