Round number POJ - 3252

  题目大意:一个"round number" 数的定义是,将它转化成2进制后,0的个数大于等于1的个数,要求的就是在[s,f]范围内"round number"的个数

  和之前的数位dp不同的是,这题是对二进制的数位进行dp,所以就存在着一个限制,前面有没有存在1,如果前面没有1.那么像00001,就是1,前面的0是不计数的,所以重点就在于考虑这个dfs时就得分前面有没有1,如果没有那么0就不计数,反之我们记录0和1的差值,取0加1,取1减1,不过需要注意的是,差值可能是负数,所以要转正数,详情见代码

 #include<cstdio>
#include<cstring>
#define ll long long
const int N=;
int up[N];
ll n,s,f,dp[N][*N][];//dp[i][j][k]代表当前为第i位,前面0和1的差值为j-N,前面有没有1的结果
//例如dp[4][50][1]就代表第4位,在第4位前面0和1差值为0,并且前面有1的结果数
ll dfs(int p,int d,bool is1,bool isu)//p 位数,d 0和1的差值,is1 该位前面有没有1 isu有没有上限
{
if(!p)//边缘状态,0大于等于1(d>=0)返回1,反之返回0
return d>=;
if(-d>p)//小剪枝,如果剩下位数全是0加起来都没有1多,返回0
return ;
if(!isu&&dp[p][d+N][is1]!=-)
return dp[p][d+N][is1];
ll ans=;
for(int i=;i<=(isu ? up[p] : );i++)
{
if(is1)//当前面有1正常记录0的差值
ans+=dfs(p-,(i ? d- : d+),is1||i,isu&&i==up[p]);
else//当前面没有1,0不计,1记-1
ans+=dfs(p-,-i,is1||i,isu&&i==up[p]);
}
if(!isu)
dp[p][d+N][is1]=ans;
return ans;
}
ll solve(ll x)
{
int num=;
while(x)
{
up[++num]=x&;
x>>=;
}
return dfs(num,,,);
}
int main()
{
ll s,f;
memset(dp,-,sizeof(dp));
while(~scanf("%lld%lld",&s,&f))
printf("%lld\n",solve(f)-solve(s-));
return ;
}

RNGRNGRNG

  关于结果的存储,不同的想法具体的dp还有也不同,有些是dp[i][j][k]是当前是第i位,前面0的个数为j,前面1的个数为k的结果有多少个,不过大体的思路还是相同的

  除数位dp外,还有一个组合数学的解法,不过相比大佬们,我的思路有点麻烦,详情见代码

 #include<cstdio>
#include<cstring>
#define ll long long
ll n,m,c[][]={},a[]={};//c组合数,a[i]长度为i,首位1在第i位存在RN的个数
//比加a[1]保存1,a[2]保存10,11,a[3]保存100,101,110,111,中满足RN的个数
//所以a[1]=0,a[2]=1,a[3]=1
int up[]={};
void init()
{
for(int i=;i<=;i++)
{
c[i][]=;
for(int j=;j<=i;j++)
{
if(j<=i/)
c[i][j]=c[i-][j-]+c[i-][j];
else
c[i][j]=c[i][i-j];
}
for(int j=i-;j>=(i+)/;j--)//首位i是1,剩下i-1位0可以i-1个,
//i-2个,假设最少取j个满足要求,那么j>=(i+1)/2(0的数目大于等于总数目的一半)
a[i]+=c[i-][j];
}
}
ll solve(ll x)
{
int num=;
while(x)
{
up[++num]=x&;
x>>=;
}
ll ans=;
for(int i=;i<num;i++)
ans+=a[i];
//假如x转化成2进制是1101
//先算上1,10~11,100~111的里的答案
if(num>)//先把1000算上
ans++;
int z=;//记录第i位前0的个数
//再来计算1000~1101之间的答案,down代表有没有计算到下界
//一开始的下界就是1000
for(int i=num-,down=;i>=;i--)
{
if(up[i])//当存在1时,例如第二位就是1,我们就求的是1000~1100的答案
{
if(down)//因为之前已经算过1000了,所以这里减去
ans--,down=;
for(int j=i-;z+j+>=(num+)/&&j>=;j--)//假设第i位是0,前面的0加上
//第i位再加上后面取的j个0,总的0的个数要大于等于总个数
ans+=c[i-][j];
if(i-+z>=(num+)/)//假设后面的i-1全是0,0的个数大于等于总个数
ans++,down=;//那么1100可以作为下界
}
else
z++;
}
return ans;
}
int main()
{
init();
while(~scanf("%lld%lld",&n,&m))
printf("%lld\n",solve(m)-solve(n-));
return ;
}

WEWEWE

二进制上的数位dpPOJ 3252的更多相关文章

  1. 图片的URL上传至阿里云OSS操作(微信小程序二维码返回的二进制上传到OSS)

    当我们从网络中获取一个URL的图片我们要存储到本地或者是私有的云时,我们可以这样操作  把url中的图片文件下载到本地(或者上传到私有云中)  public String uploadUrlToOss ...

  2. ftp设置二进制上传

    一个不重要的数据库,备份是用expdp导出,然后上传到ftp服务器上面.上周这个主机宕机了,要在别的数据库恢复,发现报如下错误: ORA-39001: invalid argument value O ...

  3. bzoj 3209 花神的数论题——二进制下的数位dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3209 可以枚举 “1的个数是...的数有多少个” ,然后就是用组合数算在多少位里选几个1. ...

  4. 前端上传图片 base64转二进制上传

    var dataURItoBlob = function (dataURI) { var byteString = atob(dataURI.split(',')[1]); var mimeStrin ...

  5. 浅谈数位DP

    在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...

  6. BZOJ3329 Xorequ(数位DP)

    题目大意:x xor 2x=3x(与x xor 3x=2x等价)求满足等式且小于n的x的个数,与满足等式小于2n的数的个数. 因为异或是不进位的二进制加法,那么因为结果正好和加法相同,那么说明x在二进 ...

  7. BZOJ 4513: [Sdoi2016]储能表 [数位DP !]

    4513: [Sdoi2016]储能表 题意:求\[ \sum_{i=0}^{n-1}\sum_{j=0}^{m-1} max((i\oplus j)-k,0) \] 写出来好开心啊...虽然思路不完 ...

  8. 【数位DP】题集

    1.[HDOJ2089] 题意:求区间内不出现4和62的数的个数 解法:模板题 2.[HDOJ3555] 题意:求区间内不出现49的数的个数 解法:模板题 3.[HDOJ5179] 题意:对于一个十进 ...

  9. 蒟蒻的数位DP专题总结

    BZOJ  1026: [SCOI2009]windy数: 题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1026           d ...

随机推荐

  1. python 文件写入

    def write_file(): """ 文件写入""" file_name = "wri2te_test.txt" ...

  2. Python 基础(十七)--序列化

    pickle模快 pickle.dumps():可将特有数据类型的转换为bytes类型 pickle.loads():将bytes类型转化回来 >>> import pickle & ...

  3. Dom编程-左侧菜单栏设计模型实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 华为设备ACL与NAT技术

    ACL 访问控制列表(Access Control Lists),是应用在路由器(或三层交换机)接口上的指令列表,用来告诉路由器哪些数据可以接收,哪些数据是需要被拒绝的,ACL的定义是基于协议的,它适 ...

  5. Autofac通过配置的方式

    autofac是比较简单易用的IOC容器.下面我们展示如何通过json配置文件,来进行控制反转. 需要用到以下程序集.可以通过nugget分别安装 Microsoft.Extensions.Confi ...

  6. 异常-throws的方式处理异常

    定义功能方法时,需要把出现的问题暴露出来让调用者去处理.那么就通过throws在方法上标识. package cn.itcast_05; import java.text.ParseException ...

  7. 完美解决Uncaught SyntaxError: Unexpected end of input

    Unexpected end of input  的英文意思是“意外的终止输入” 他通常表示我们浏览器在读取我们的js代码时,碰到了不可预知的错误,导致浏览器 无语进行下面的读取 通常造成这种错误的原 ...

  8. Flutter-动画-实践篇

    一.了解AnimatedWidget 通常我们给一个Widget添加动画的时候都需要监听Animation的addListener()方法,并在这个方法里面不停的调用setState()方法通知Wei ...

  9. spring framework体系结构及模块jar依赖关系

    本文对于Spring的JAR包使用和配置,结合网友材料以spring 4.3.6.RELEASE版本为例,介绍spring框架结构和各模块对应JAR包以及模块间JAR依赖关系. 注:不同版本JAR包依 ...

  10. python3之POST请求URL

    方法一:使用requests模块 import requests as rq import json def funcpost(): url = 'http://www.***.com/' # 需要请 ...