###POJ 3252 题目链接 ###

题目大意:给你一段区间 [Start,Finish] ,在这段区间中有多少个数的二进制表示下,0 的个数 大于等于 1 的个数。


分析:

1、很显然是数位DP,枚举这区间中所有数的二进制位数。由于与 0 的个数有关,故需要用 lead 标记前导零情况。

2、然后就是要处理 1 的个数与 0 的个数,故 dp 的第二维状态即要表示出枚举到当前位 pos 时所拥有的 0 的个数 (或 1)。

但是你会发现,如果当前知道的是 前面几位中 0 的个数,为了满足题意,我还需要知道前面几位中 1 的个数,然后求差值,再到后面 pos 位中找相应的 dp 值。故为了简便,第二维设的应该是当前 1~pos位中,1的个数减去 0 的个数的差值。由于差值可能为负数,且 20亿 最高不会超过 32 位(二进制),故取 32 为中间值,然后根据枚举位上的 1 或 0 来加减。

故 dp[i][j] 表示,在 1~ i 位中,1 与 0 的个数差值为 j (与 32 的差值)。

本题的记忆化搜索: 当从最高位枚举到第 pos 位时,第 1 ~ pos 位上与当前状态对应于 dp[pos][差值] 时满足条件的个数,这个差值来源于 最高位到 pos 位 。比如从最高位的前三位都为 1 ,那么此时从最高位枚举了 3 位,且sum = 32 + 3 = 35 ,那么 dp[pos][sum] 即求在 sum 为 35 的情况下,第 1 ~ pos 位上,能使得最后 sum<=32 的状态个数。

代码如下:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int dp[][],a[];
int N,M,res;
int dfs(int pos,int sum,bool lead,bool limit){
if(pos==) return sum<=;
if(!limit&&!lead&&dp[pos][sum]!=-) return dp[pos][sum];
int up=limit?a[pos]:;
int ans=;
for(int i=;i<=up;i++){
if(lead&&i==) ans+=dfs(pos-,sum,lead,limit&&i==a[pos]);
else ans+=dfs(pos-,sum+(i==?-:),false,limit&&i==a[pos]);
}
if(!limit&&!lead) dp[pos][sum]=ans;
return ans;
}
int solve(int x)
{
int pos=;
while(x){
a[++pos]=(x&);
x>>=;
}
res=pos;
return dfs(pos,,true,true);
}
int main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
memset(dp,-,sizeof(dp));
while(~scanf("%d%d",&N,&M)){
printf("%d\n",solve(M)-solve(N-) );
}
}

POJ 3252 (数位DP)的更多相关文章

  1. [poj 3252]数位dp前导0的处理

    通过这个题对于数位dp中前导0的处理有了新的认识. 题目链接:http://poj.org/problem?id=3252 //http://poj.org/problem?id=3252 #incl ...

  2. poj 3252 数位dp

    题意:一个二进制的数,如果0的个数大于1的个数,那么我们称这个数为Round Numbers,求给定区间(十进制表示)中Round Numbers的个数 题解:数位dp,不过这里枚举的时候lead标记 ...

  3. poj 3252 Round Numbers 数位dp

    题目链接 找一个范围内二进制中0的个数大于等于1的个数的数的数量.基础的数位dp #include<bits/stdc++.h> using namespace std; #define ...

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

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

  5. POJ 3252 Round Number(数位DP)

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

  6. POJ 3252 区间内一个数的二进制中0的数量要不能少于1的数量(数位DP)

    题意:求区间内二进制中0的数量要不能少于1的数量 分析:很明显的是数位DP: 菜鸟me : 整体上是和数位dp模板差不多的 , 需要注意的是这里有前导零的影响 , 所以需要在dfs()里面增加zor ...

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

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

  8. $POJ$3252 $Round\ Numbers$ 数位$dp$

    正解:数位$dp$ 解题报告: 传送门$w$ 沉迷写博客,,,不想做题,,,$QAQ$口胡一时爽一直口胡一直爽$QAQ$ 先港下题目大意嗷$QwQ$大概就说,给定区间$[l,r]$,求区间内满足二进制 ...

  9. POJ 3689 Apocalypse Someday [数位DP]

    Apocalypse Someday Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 1807   Accepted: 87 ...

随机推荐

  1. 05Shell循环语句

    循环语句 for 语法结构 for 变量名 [ in 取值列表 ] do 循环体 done 注意 当for对文件内容进行逐行处理时,会忽略空行 示例 例1 ping 主机的脚本(初始版):缺点执行过程 ...

  2. 巧妙利用selenium中的JS操作来处理特殊的文本框

    在使用selenium对页面进行相关操作时,有时候会遇到以下三种情况: 1.日期框:无法直接输入文本,必须要选择某一天的日期并点击才会填入文本框: 2.检索框:可以直接输入文本,但必须要点击根据输入的 ...

  3. selenium常用的三种等待方式

    一.强制等待 使用方法:sleep(X),等待X秒后,进行下一步操作. 第一种也是使用最简单的一种办法就是强制等待sleep(X),强制让浏览器等待X秒,不管当前操作是否完成,是否可以进行下一步操作, ...

  4. bootstrap 输入框后面有个按钮

    效果如下:  实现代码:

  5. Nginx 极简教程(快速入门)

    作者:dunwu github.com/dunwu/nginx-tutorial 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计模式内容聚合 4.  ...

  6. Zabbix 预警问题-预警对应的用户报警媒介收不到

    问题背景 公司现在有这种需求,需要我们对关键的预警发送到对应的项目组负责人,比如 保险项目组的服务器预警大于警告的预警发送到保险负责人的邮箱(也会发送给运维的,背锅逃不掉的). 进行创建一个 用户群组 ...

  7. webpack资源处理

    使用上篇已谈过,这篇纯代码!!~~ <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  8. Oracle 12C Win 10 安装 应用 总结

    安装参考 https://www.cnblogs.com/onezg/p/8768597.html 我当时安装的是Oracle 12c Release 1(Version 12.1.0.1.0,64位 ...

  9. 比较好用的移动端适配的两种方案及flexible和px2rem-loader在webpack下的配置

    移动端适配,目前自己常用的两种 方案,参考以下两篇好文 方案一:使用lib-flexible包 https://www.w3cplus.com/mobile/lib-flexible-for-html ...

  10. curl http libcurl 功能使用

    /* * This example shows a HTTP PUT operation. PUTs a file given as a command * line argument to the ...