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. F. 汤圆防漏理论

    ghc很喜欢吃汤圆,但是汤圆很容易被粘(zhān)漏. 根据多年吃汤圆经验,ghc总结出了一套汤圆防漏理论: 互相接触的汤圆容易粘(zhān)在一起,并且接触面积不同,粘(zhān)在一起的粘(niá ...

  2. Ruby Rails学习中:User 模型,验证用户数据

    用户建模 一. User 模型 实现用户注册功能的第一步是,创建一个数据结构,用于存取用户的信息. 在 Rails 中,数据模型的默认数据结构叫模型(model,MVC 中的 M).Rails 为解决 ...

  3. PostgreSQL查看表、表索引、视图、表结构以及参数设置

    -- 表索引select * from pg_indexes where tablename='person_wechat_label';select * from pg_statio_all_ind ...

  4. 界面(UI)测试基础

    界面测试,在web程序雏形后就持续测试到项目交付. 项目中的界面测试 此刻需要感慨下“产品经理”的重要性:没有产品把关整个项目,做出来的东西只能叫做“程序”而非“产品” 有产品的工作流,测试在界面测试 ...

  5. java线程的方便调用方式

    一直用java的线程,总感觉写起来阅读或书写起来不是方便,改进之. 实现类: public class Task<R> { private ExecutorService executor ...

  6. Ubuntu14.04更新硬件实现堆栈(HWE)

    Ubuntu14.04更新硬件实现堆栈(HWE) 来源: https://github.com/gatieme/AderXCoding/tree/master/system/tools/ubuntu_ ...

  7. kali安装开启ssh & 安装docker

    ssh相关 一.配置SSH参数 . 修改sshd_config文件,命令为: vi /etc/ssh/sshd_config 将#PasswordAuthentication no的注释去掉,并且将N ...

  8. KMS激活的密钥

    今天办公电脑黑屏了,仔细一看,变成了未激活.于是从网上找到了所有Windows版本的GVLK密钥,试了一下完美激活,应该是180天的吧.先用着,等下次过期了再说,哈哈. GVLK密钥是专门用于KMS激 ...

  9. PHP的八种数据类型

    PHP 支持8种基本的数据类型. 四种标量类型: boolean (布尔型) integer (整型) float (浮点型, 也称作 double) string (字符串) 两种复合类型: arr ...

  10. python文件操作:文件处理与操作模式

    一,文件处理的模式基本概念 #coding:utf-8 # 一: 文件处理的三个步骤 # 1. 打开文件拿到文件对象(文件对象====>操作系统打开文件====>硬盘) # f=open( ...