题目大意:

求区间 \([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;
}

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

  1. poj3252 Round Numbers(数位dp)

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

  2. POJ3252 Round Numbers 【数位dp】

    题目链接 POJ3252 题解 为什么每次写出数位dp都如此兴奋? 因为数位dp太苟了 因为我太弱了 设\(f[i][0|1][cnt1][cnt0]\)表示到二进制第\(i\)位,之前是否达到上界, ...

  3. POJ 3252 Round Numbers(数位dp)

    题意:给定区间[l,r],l < r ,求区间中满足条件的正整数的个数:二进制表示下0的个数不少于1的个数. 分析:f(x)表示<=x时满足条件的数的个数,所求问题即为f(r)-f(l-1 ...

  4. [BZOJ1662][POJ3252]Round Numbers

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

  5. POJ3252 Round Numbers —— 数位DP

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

  6. poj3252 Round Numbers (数位dp)

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

  7. Codeforces Round #235 (Div. 2) D. Roman and Numbers (数位dp、状态压缩)

    D. Roman and Numbers time limit per test 4 seconds memory limit per test 512 megabytes input standar ...

  8. Codeforces Beta Round #51 D. Beautiful numbers(数位dp)

    题目链接:https://codeforces.com/contest/55/problem/D 题目大意:给你一段区间[l,r],要求这段区间中可以整除自己每一位(除0意外)上的数字的整数个数,例如 ...

  9. poj3252 Round Numbers

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

随机推荐

  1. Spark Steaming消费kafka数据条数变少问题

    对于基于Receiver 形式,我们可以通过配置 spark.streaming.receiver.maxRate 参数来限制每个 receiver 每秒最大可以接收的记录的数据:对于 Direct ...

  2. Java 内存模型及GC原理 (转)

      来源:http://blog.csdn.net/ithomer/article/details/6252552 一个优秀Java程序员,必须了解Java内存模型.GC工作原理,以及如何优化GC的性 ...

  3. codeforces 609B

    #include<bits/stdc++.h> using namespace std; ]; int main() { memset(num,,sizeof(num)); int n,m ...

  4. Native memory allocation (mmap) failed to map 142606336 bytes for committing reserved memory.

    这里写链接内容 问题描述 Java程序运行过程中抛出java.lang.OutOfMemoryError: unable to create new native thread,如下所示: [java ...

  5. Spring Data Jpa 简单使用事务

    对于两张表,需要顺序操作,必须全部表均操作成功才可,否则两张表不操作. 例如,现在有device,collectionpoint两张表,向两张表顺序执行insert操作 SQL如下 INSERT IN ...

  6. VC++ CMsflexgrid 使用

    引用actvie x :microsoft CMsflexgrid; BOOL CCalibrationCoordsDisDlg::OnInitDialog() { CDialog::OnInitDi ...

  7. springBoot中使用使用junit测试文件上传,以及文件下载接口编写

    本篇文章将介绍如何使junit在springBoot中测试文件的上传,首先先阅读如何在springBoot中进行接口测试. 文件上传操作测试代码 import org.junit.Before; im ...

  8. ZOJ Problem Set - 1090——The Circumference of the Circle

      ZOJ Problem Set - 1090 The Circumference of the Circle Time Limit: 2 Seconds      Memory Limit: 65 ...

  9. git 上传当前分支

    因为我现在的分支是的名很长,每次需要上次当前分支需要写很多代码,是不是有很简单方法上传当前分支. 如果要上传一个分支到仓库 origin 那么就需要使用下面的命令 git push origin 分支 ...

  10. 【Jenkins】pipeline-hello-world项目

    1.New Item 2.Pipeline Definition 3.Build Error 4.Solution 5.Console Output