POJ 3252 (数位DP)
题目大意:给你一段区间 [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)的更多相关文章
- [poj 3252]数位dp前导0的处理
通过这个题对于数位dp中前导0的处理有了新的认识. 题目链接:http://poj.org/problem?id=3252 //http://poj.org/problem?id=3252 #incl ...
- poj 3252 数位dp
题意:一个二进制的数,如果0的个数大于1的个数,那么我们称这个数为Round Numbers,求给定区间(十进制表示)中Round Numbers的个数 题解:数位dp,不过这里枚举的时候lead标记 ...
- poj 3252 Round Numbers 数位dp
题目链接 找一个范围内二进制中0的个数大于等于1的个数的数的数量.基础的数位dp #include<bits/stdc++.h> using namespace std; #define ...
- poj 3252 Round Numbers(数位dp 处理前导零)
Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...
- POJ 3252 Round Number(数位DP)
Round Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6983 Accepted: 2384 Des ...
- POJ 3252 区间内一个数的二进制中0的数量要不能少于1的数量(数位DP)
题意:求区间内二进制中0的数量要不能少于1的数量 分析:很明显的是数位DP: 菜鸟me : 整体上是和数位dp模板差不多的 , 需要注意的是这里有前导零的影响 , 所以需要在dfs()里面增加zor ...
- POJ 3252 Round Numbers(数位dp&记忆化搜索)
题目链接:[kuangbin带你飞]专题十五 数位DP E - Round Numbers 题意 给定区间.求转化为二进制后当中0比1多或相等的数字的个数. 思路 将数字转化为二进制进行数位dp,由于 ...
- $POJ$3252 $Round\ Numbers$ 数位$dp$
正解:数位$dp$ 解题报告: 传送门$w$ 沉迷写博客,,,不想做题,,,$QAQ$口胡一时爽一直口胡一直爽$QAQ$ 先港下题目大意嗷$QwQ$大概就说,给定区间$[l,r]$,求区间内满足二进制 ...
- POJ 3689 Apocalypse Someday [数位DP]
Apocalypse Someday Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 1807 Accepted: 87 ...
随机推荐
- js的事件循环(Event Loop)
(本文从掘金小册整理) 首先介绍一下几个概念 进程与线程 相信大家经常会听到 JS 是单线程执行的,但是你是否疑惑过什么是线程? 讲到线程,那么肯定也得说一下进程.本质上来说,两个名词都是 CPU 工 ...
- go语言中map每次遍历的顺序不同-问题分析
WHAT? 发现下面这段代码,多次运行出的结果是不一样的 mapper := make(map[int]string) mapper[1] = "1" mapper[2] = &q ...
- 【git】代码回退指定commit
[注意:如果提交的错误代码较少,可以在本地修改成 commit之前的正确代码样子,然后再提交一次即可.不用麻烦的操作回滚.] 开发人员错误将代码提交到gitlab的远程dev分支,回滚方法如下: 1. ...
- java基础(16):正则表达式、Date、DateFormat、Calendar
1. 正则表达式 1.1 正则表达式的概念 正则表达式(英语:Regular Expression,在代码中常简写为regex). 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配 ...
- 面试官常问的Nginx的那几个问题?
什么是Nginx? Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器 Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代 ...
- 顺F分享,你是在裸奔吗?
" 对顺F旗下各APP顺藤摸瓜分析--顺F分享." 前文对顺F速运和顺F速运国际版进行了分析,二者使用同一套接口,虽然保护强度不高,但对代码和数据的保护却区别对待,实在让人诧异. ...
- 告诉你如何在Xcode中安装炫酷的插件!!!!!
(如果你已经有了自己喜欢的插件,你可以直接找到该插件的下载地址,下载下来,参照下面的步骤来安装到Xcode工程之中) 如果还没有找到自己想要的插件,那么推荐你在开源中国社区http://www.osc ...
- 【Gradle】Gradle构建脚本基础
Gradle构建脚本基础 Settings文件 在Gradle中,定义了一个设置文件,用于初始化以及工程树的配置.设置文件的默认名为settings.gradle,放在根工程目录下. 设置文件大多数的 ...
- NSCach 的知识小记
(1)NSCach 可以设置最大缓存数据的数量,如果超出该限制那么内部会自动开启一个回收过程把最先存储的数据删除 (2)NSCach 可以设置代理,<NSCachDelegate>,可以监 ...
- 登陆远程服务器的Tomcat 8的manger的页面403
访问远程服务器Tomcat 8的管理页面报错 在远程服务器上安装了一个tomcat8.5,配置好用户后重新启动tomcat ,发现:8080可以访问,但是进入:8080/manager/html页面报 ...