题目大意:给你一个区间$[l,r]$,求在该区间内有多少整数在二进制下$0$的数量$≥1$的数量。数据范围$1≤l,r≤2*10^{9}$。

第一次用记忆化dfs写数位dp,感觉神清气爽~(原谅我这个蒟蒻,原先写的四不像数位dp至少需2h,用真记忆化dfs不到半小时写出)

我们用$f[i][j]$表示在最后的$i+j$为中,用了$i$个$0$,$j$个$1$的方案数(第$i+j$位也可以是$0$)。该方程转移显然为$f[i][j]=f[i-1][j]+f[i][j-1]$。

于是我们用记忆化dfs去求答案,$dfs(n,op,x,y)$表示你构造到从后往前数第$n$位,是否有压着上限,$0$的数量,$1$的数量。

若无压着上限,则答案显然为$dfs(n-1,op,x,y-1)+dfs(n-1,op,x-1,y)$。

若压着上限且第$num[n]$位为$0$,则答案为$dfs(n-1,op,x-1,y)$。 否则答案为$dfs(n-1,op,x,y-1)+dfs(n-1,op^1,x-1,y)$。

搜索时用记忆化加速即可。

 #include<iostream>
#include<cstdio>
#include<cstring>
#define L int
#define M 50
using namespace std;
L f[M][M]={};//前i+j位中,用了i个0,j个1的方案数
int num[M]={},cnt=;
L dfs(int n,bool op,int x,int y){//当前处理到第n位,且第cnt位到第n+1为已经确定,第n-1位是否压着上限,计划用x个0,和y个1。
if(x==-||y==-) return ;
if(!op&&f[x][y]!=-) return f[x][y];
if(!op){
f[x][y]=dfs(n-,op,x-,y)+dfs(n-,op,x,y-);
return f[x][y];
}
if(!num[n]) return dfs(n-,op,x-,y);
return dfs(n-,,x-,y)+dfs(n-,op,x,y-);
}
L get(L x){
if(x==) return ;
memset(num,,sizeof(num)); cnt=;
int b[]={};
while(x){
num[++cnt]=x&;
b[x&]++; x>>=;
}
L sum=;
if(b[]>=b[]) sum++;
for(int i=;i<=cnt;i++){
for(int j=;j*<=i;j++)
sum+=dfs(i-,i==cnt,i-j,j-);
}
return sum;
}
int main(){
L a,b;
while(cin>>a>>b){
memset(f,-,sizeof(f));
for(int i=;i<M;i++) f[][i]=f[i][]=;
printf("%d\n",get(b)-get(a-));
} }

【poj3252】 Round Numbers (数位DP+记忆化DFS)的更多相关文章

  1. POJ3252 Round Numbers —— 数位DP

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

  2. poj3252 Round Numbers (数位dp)

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

  3. HDU3709:Balanced Number(数位DP+记忆化DFS)

    Problem Description A balanced number is a non-negative integer that can be balanced if a pivot is p ...

  4. poj3252 Round Numbers[数位DP]

    地址 拆成2进制位做dp记搜就行了,带一下前导0,将0和1的个数带到状态里面,每种0和1的个数讨论一下,累加即可. WA记录:line29. #include<iostream> #inc ...

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

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

  6. 数位dp/记忆化搜索

    一.引例 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an  ...

  7. [hihocoder 1033]交错和 数位dp/记忆化搜索

    #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1 ...

  8. [poj3252]Round Numbers_数位dp

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

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

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

随机推荐

  1. for() 和$.each()的用法区别

    一.对于数组 var arr=['姚明','易建联','张继科']; $.each(arr,function(index,value){ document.write(index+"=&qu ...

  2. 2018.10.13 bzoj1070: [SCOI2007]修车(费用流)

    传送门 费用流经典题目. 自我感觉跟TheWindy′sThe Windy'sTheWindy′s很像. 利用费用提前计算的思想来建图就行了. 代码: #include<bits/stdc++. ...

  3. qmake-how to

    简单例子 假设已经实现如下程序: hello.cpphello.hmain.cpp 首先,使用编辑器,在上述文件目录下创建文件hello.pro.然后加入几行语句告诉qmake项目中的源文件和头文件. ...

  4. VS2013支持多字节的方法

    参考链接: https://jingyan.baidu.com/article/6181c3e06ab30f152ff1534d.html

  5. IntelliJ IDEA 14 Keygen

    package keygen; import java.math.BigInteger; import java.util.Date; import java.util.zip.CRC32; publ ...

  6. hdu1251 && hud 1247 (字典树)

    hdu1251 题目 这道题,主要是在主函数的输入输出上犹豫了. #include<stdio.h> #include<cstring> #include<iostrea ...

  7. Ansible之ansible-playbook roles

    刚开始学习运用 playbook 时,可能会把 playbook 写成一个很大的文件,到后来可能你会希望这些文件是可以方便去重用的,所以需要重新去组织这些文件. 基本上,使用 include 语句引用 ...

  8. C++实现wc.exe程序

    github项目地址:https://github.com/insomniali/wc 基本功能 wc.exe -c file     统计文件file的字符数  [实现] wc.exe -w fil ...

  9. BMDThread控件动态创建多线程示例

    http://www.cnblogs.com/railgunman/archive/2010/12/08/1900688.html BMDThread控件是一套相当成熟的线程控件,使用它可以让你快速的 ...

  10. Android-ByteUtil工具类

    Byte处理转换相关的工具类: public class ByteUtil { private ByteUtil(){} /** * 把byte[] 转成 Stirng * @param bytes ...