POJ3252 Round Numbers 题解 数位DP

题目大意:
求区间 \([x,y]\) 范围内有多少数的二进制表示中的‘0’的个数 \(\ge\) ‘1’的个数。

解题思路:
使用 数位DP 解决这个问题。

我们设状态 f[pos][num0][num1][all0] 表示在:

  • 当前所在数位为 pos
  • 当前选择的‘0’的个数为 num0
  • 当前选择的‘1’的个数为 num1
  • 到当前位位置是不是前面的数都是前导零(如果都是前导0则 all0==true,否则 all==false)。

下的方案数。

我们开函数 dfs(int pos, int num0, int num1, bool all0, bool limit) 来解决这个问题。
其中,

  • posnum0num1all0 所表示的含义和上述表述一致,
  • limit 表示当前是否处于限制条件。

实现代码如下:

#include <cstdio>
#include <cstring>
int f[33][33][33][2], a[33];
void init() {
    memset(f, -1, sizeof(f));
}
int dfs(int pos, int num0, int num1, bool all0, bool limit) {
    if (pos < 0)    // 遍历完所有数位
        return num0 >= num1 ? 1 : 0;
    if (num0 + pos + 1 < num1)  // 0的个数用于达不到1的个数
        return 0;
    if (!limit && f[pos][num0][num1][all0] != -1) return f[pos][num0][num1][all0];
    int up = limit ? a[pos] : 1;
    int tmp = 0;
    for (int i = 0; i <= up; i ++) {
        tmp += dfs(pos-1, num0 + (!all0 && i==0), num1 + (i==1), all0 && i==0, limit && i==up);
    }
    if (!limit) f[pos][num0][num1][all0] = tmp;
    return tmp;
}
int get_num(int x) {
    int pos = 0;
    while (x) {
        a[pos++] = x % 2;
        x /= 2;
    }
    return dfs(pos-1, 0, 0, true, true);
}
int main() {
    init();
    int x, y;
    while (~scanf("%d%d", &x, &y)) {
        printf("%d\n", get_num(y) - get_num(x-1));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/quanjun/p/11972218.html

时间: 2024-11-08 03:13:23

POJ3252 Round Numbers 题解 数位DP的相关文章

POJ-3252 Round Numbers (数位DP)

Round Numbers http://poj.org/problem?id=3252 Time Limit: 2000MS   Memory Limit: 65536K       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,

POJ3252 Round Numbers 组合数学||数位DP

这题目做了两个小时,调试的头都晕了... 题型是数位DP中很常见的,给一个区间[l,r]求区间[l,r]中的 符合题目要求的数的个数,本题求的 是 区间中 的数  它的二进制中0的个数大于等于1的个数的    这些数的个数,不好意思表达能力有点差...例如[1,4]答案是2, 因为 2的二进制是10,0的个数大于等于1的个数,4的二进制是100,0的个数大于1的个数,所以答案是两个 好了第一反应肯定是 设定一个函数 f(r) - f[l - 1]就是答案,那么显然这个函数f(r)的意思就是 1

poj 3252 Round Numbers(数位DP)

Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11003   Accepted: 4064 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',

POJ-3252——Round Numbers

POJ-3252——Round Numbers 传送门:http://poj.org/problem?id=3252 题意:求n-m中二进制表示0的数量不小于1的数的个数 要找二进制0和1的个数,因为是按位数来找的,可以考虑数位dp 状态dp[pos][_0][_1] 表示为dp[当前第几位][含0的个数][含1的个数] 这个题注意dfs传参的时候要多传进去一个lead(是否是前导0)因为此时前导0的存在会影响最终的答案 之前的数位dp都是在十进制的基础上dp,而本题是二进制,拆分的时候拆成二进

LightOJ 1205 - Palindromic Numbers (数位dp)

LightOJ 1205 - Palindromic Numbers (数位dp) ACM 题目地址:SPOJ MYQ10 Mirror Number 题意: 求[a,b]中回文的个数. 分析: 是SPOJ MYQ01的简单版...其实有非递归方法的. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * Blog: http://blog.csdn.net/hcbbt * File: 1205.cpp * Create Date: 2014-08-

Educational Codeforces Round 8(D. Magic Numbers(数位DP))

题目链接:点击打开链接 题意:给一个m一个d, 一个字符串a和b, 问在[a,b]范围内, 有多少个可以整除m的魔法数, 魔法数的定义是, 偶数位上都是d, 奇数位上都不是d. 思路:据说是典型的数位DP, 以前没做过数位DP, 感觉和DP差不多? 用d[i][j][p]表示当前到了第i位, 余数为j, p == 1表示目前和b串相等, p == 0表示已经比b串小了.  每次枚举第i位上放的数, 转移就行了. 区间也好弄, 我们可以先处理出小于等于b的所有情况ans1, 小于等于a的所有情况a

poj3252 Round Numbers

Round Numbers POJ - 3252 题目大意: 输入两个十进制正整数a和b,求闭区间[a,b]内有多少个Round Number? 所谓的Round Number就是一个把十进制数转换成一个无符号二进制数,若该二进制数中0的个数大于等于1的个数,则它就是一个Round Number. 注意 转换所得的二进制数,最高位必然是1,最高位前不允许有0 /* 以前用的组合数学,听说dalao也用数位dp做,我也来一下 */ #include<iostream> #include<c

SPOJ BALNUM Balanced Numbers(数位dp,状态压缩)

BALNUM - Balanced Numbers no tags 题目链接 Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if: 1)      Every even digit appears an odd number of times in its decimal representation 2)   

spoj RAONE - Ra-One Numbers (数位dp)

RAONE - Ra-One Numbers no tags In the War between good and evil . Ra-One is on the evil side and G-One on the good side. Ra-One is fond of destroying cities and its G-one's duty to protect them.. Ra-One loves to destroy cities whose Zip Code has spec