洛谷 P6218 [USACO06NOV] Round Numbers S

题目描述

如果一个正整数的二进制表示中,\(0\) 的数目不小于 \(1\) 的数目,那么它就被称为「圆数」。

例如,\(9\) 的二进制表示为 \(10011001\),其中有 \(2\) 个 \(0\) 与 \(2\) 个 \(1\)。因此,\(9\) 是一个「圆数」。

请你计算,区间 \([l,r]\) 中有多少个「圆数」。

输入格式

一行,两个整数 \(l,r\)。

输出格式

一行,一个整数,表示区间 \([l,r]\)中「圆数」的个数。

输入输出样例

输入 #1

2 12

输出 #1

6

说明/提示

【数据范围】

对于 \(100\%\) 的数据,\(1\le l,r\le 2\times 10^9\)。

【样例说明】

区间 \([2,12]\) 中共有 \(6\) 个「圆数」,分别为 \(2,4,8,9,10,12\)

分析

比较套路的数位 \(DP\)

数位 \(DP\) 的实质就是换一种暴力枚举的方式,使得新的枚举方式满足 \(DP\) 的性质,然后记忆化就可以了。

首先,我们要进行 \(DP\) 的话,肯定要定义一个 \(f\) 数组存储我们计算过的值

因为这道题和数位有关,所以第一位我们要定义当前遍历到了第几位

而且我们还要判断二进制下 \(0\) 的数量和 \(1\) 的数量

所以,我们设 \(f[i][j][k]\) 为当前遍历到第 \(i\) 位,二进制下 \(1\) 的数量为 \(j\),\(0\) 的数量为 \(j\) 的数的个数

主函数我们用差分的思想搞一下即可

signed main(){
memset(f,-1,sizeof(f));
int l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",solve(r)-solve(l-1));
return 0;
}

然后是 \(solve\) 函数

这里的 \(cnt\) 是用来记录当前的数在二进制下有多少位,\(num\) 数组是用来记录这个数每一二进制位上的数字的

这个函数的变量只有一个 \(xx\), 返回值是 \(0\) 到 \(xx\) 之间圆数的个数

int solve(int xx){
memset(num,0,sizeof(num));
cnt=0;
while(xx){
num[++cnt]=xx&1ll;
xx>>=1ll;
}
return dfs(cnt,0,0,1,1);
}

下面的 \(dfs\) 函数是最重要的部分

int dfs(int ws,int tot1,int tot0,bool lim,bool zer){
if(ws==0) {
if(tot1<=tot0) return 1;
return 0;
}
if(lim==0 && zer==0 && f[ws][tot1][tot0]!=-1) return f[ws][tot1][tot0];
int up=1,ans=0;
if(lim) up=num[ws];
for(int i=0;i<=up;i++){
if(zer==1 && i==0) ans+=dfs(ws-1,0,0,lim && i==up,1);
else ans+=dfs(ws-1,tot1+(i==1),tot0+(i==0),lim && i==up,0);
}
if(lim==0 && zer==0)f[ws][tot1][tot0]=ans;
return ans;
}

它的五个参数分别为:当前处理到第 \(ws\) 位

\(0\) 的个数 \(tot0\) ,\(1\) 的个数 \(tot1\)

\(lim\) 特判前一位是否为范围内的最大值

\(zer\) 记录有没有前导零

终止条件就是处理到最后一位

具体的边界看一下下面的模板

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
int f[60][60][60],num[55],cnt,sum[55];
const int mod=1e7+7;
int dfs(int ws,int tot1,int tot0,bool lim,bool zer){
if(ws==0) {
if(tot1<=tot0) return 1;
return 0;
}
if(lim==0 && zer==0 && f[ws][tot1][tot0]!=-1) return f[ws][tot1][tot0];
int up=1,ans=0;
if(lim) up=num[ws];
for(int i=0;i<=up;i++){
if(zer==1 && i==0) ans+=dfs(ws-1,0,0,lim && i==up,1);
else ans+=dfs(ws-1,tot1+(i==1),tot0+(i==0),lim && i==up,0);
}
if(lim==0 && zer==0)f[ws][tot1][tot0]=ans;
return ans;
}
int solve(int xx){
memset(num,0,sizeof(num));
cnt=0;
while(xx){
num[++cnt]=xx&1ll;
xx>>=1ll;
}
return dfs(cnt,0,0,1,1);
}
signed main(){
memset(f,-1,sizeof(f));
int l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",solve(r)-solve(l-1));
return 0;
}

洛谷 P6218 [USACO06NOV] Round Numbers S的更多相关文章

  1. 【题解】P6218 [USACO06NOV] Round Numbers S

    题目传送门 这是一道数位DP. 令 \(dp_{i,j,k}\) 为满足由 \(i\) 位组成,且其中有 \(j\) 个1,第 i 位(从右往左数)为 \(k\) 的二进制数的数量. 可以得出状态转移 ...

  2. 洛谷P1879 [USACO06NOV]玉米田Corn Fields(状压dp)

    洛谷P1879 [USACO06NOV]玉米田Corn Fields \(f[i][j]\) 表示前 \(i\) 行且第 \(i\) 行状态为 \(j\) 的方案总数.\(j\) 的大小为 \(0 \ ...

  3. 洛谷P2866 [USACO06NOV]糟糕的一天Bad Hair Day

    P2866 [USACO06NOV]糟糕的一天Bad Hair Day 75通过 153提交 题目提供者洛谷OnlineJudge 标签USACO2006云端 难度普及/提高- 时空限制1s / 12 ...

  4. 【题解】洛谷P1879 [USACO06NOV] Corn Fields(状压DP)

    洛谷P1879:https://www.luogu.org/problemnew/show/P1879 思路 把题目翻译成人话 在n*m的棋盘 每个格子不是0就是1 1表示可以种 0表示不能种 相邻的 ...

  5. 洛谷P1467 循环数 Runaround Numbers

    P1467 循环数 Runaround Numbers 89通过 233提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 循环数是 ...

  6. 洛谷 P1879 [USACO06NOV]玉米田 解题报告

    P1879 [USACO06NOV]玉米田Corn Fields 题目描述 农场主\(John\)新买了一块长方形的新牧场,这块牧场被划分成\(M\)行\(N\)列\((1 ≤ M ≤ 12; 1 ≤ ...

  7. 洛谷P2867 [USACO06NOV]大广场Big Square

    P2867 [USACO06NOV]大广场Big Square 题目描述 Farmer John's cows have entered into a competition with Farmer ...

  8. 洛谷——P2865 [USACO06NOV]路障Roadblocks

    P2865 [USACO06NOV]路障Roadblocks 题目描述 Bessie has moved to a small farm and sometimes enjoys returning ...

  9. 洛谷 P2867 [USACO06NOV]大广场Big Square

    P2867 [USACO06NOV]大广场Big Square 题目描述 Farmer John's cows have entered into a competition with Farmer ...

随机推荐

  1. MongoDB 事务,复制和分片的关系

    摘要:本文尝试对Mongo的复制和分布式事务的原理进行描述,在必要的地方,对实现的正确性进行论证,希望能为MongoDB内核爱好者提供一些参考. 1.前言 MongoDB基于wiredTiger提供的 ...

  2. maven项目原型(idea)

    1: internal -> appfuse-basic-jsf (创建一个基于Hibernate,Spring和JSF的Web应用程序的原型) 2: internal -> appfus ...

  3. ~~网络编程(八):UDP~~

    进击のpython ***** 网络编程--UDP 那现在看到这里的 这就是网络编程的最后一讲了 上面讲的都是关于TCP的编程方法 还记得TCP和UDP传输的区别吗? UDP简单就简单到它可以不借助管 ...

  4. socket网络

    Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...

  5. 3. 懂了这些,方敢在简历上说会用Jackson写JSON

    你必须非常努力,才能看起来毫不费力.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众 ...

  6. php imap 那些坑

    今天调试php 接收邮件,遇见的几大坑! 第一,返回错误 关键字imap_open返回flase 原来{{$mailServer}:143}INBOX  的端口,不是根据outlook给的,,,,,是 ...

  7. Java数据结构和算法(1)之队列

    1.队列的基本概念 队列(queue)是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插 ...

  8. react-router分析 - 一、history

    react-router基于history库,它是一个管理js应用session会话历史的js库.它将不同环境(浏览器,node等)的变量统一成了一个简易的API来管理历史堆栈.导航.确认跳转.以及s ...

  9. 基于.NetCore3.1系列 —— 日志记录之日志配置揭秘

    一.前言 在项目的开发维护阶段,有时候我们关注的问题不仅仅在于功能的实现,甚至需要关注系统发布上线后遇到的问题能否及时的查找并解决.所以我们需要有一个好的解决方案来及时的定位错误的根源并做出正确及时的 ...

  10. ABAP 动态备份自建表数据到新表(自建表有数据的情况下要改字段长度或者其他)

    当abaper开发好一个程序给用户使用一段时间后,发现某个字段的长度需要修改,但数据库表中已经存在很多数据,冒然直接改表字段可能会导致数据丢失,这种问题的后果可能非常严重. 所以我想到先复制出一个新表 ...