首页 > 其他分享 >P6218 [USACO06NOV] Round Numbers S 题解

P6218 [USACO06NOV] Round Numbers S 题解

时间:2024-08-19 17:17:32浏览次数:8  
标签:cnt int 题解 sum0 qd USACO06NOV 前导 Round dp

题面

题目传送门

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

例如,99 的二进制表示为 10011001,其中有 22 个 00 与 22 个 11。因此,99 是一个「圆数」。

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


前置芝士

1.数位dp
相关的题:P4317 花神的数论题


思路

l,r的数据范围为2e9,显然不能用暴力枚举

数位 DP:用来解决一类特定问题,这种问题比较好辨认,一般具有这几个特征:
1.要求统计满足一定条件的数的数量(即,最终目的为计数);
2.这些条件经过转化后可以使用「数位」的思想去理解和判断;
3.输入会提供一个数字区间(有时也只提供上界)来作为统计的限制;
4.上界很大(比如 10^{18}),暴力枚举验证会超时。

看到上面从oiwiki里抄的描述,发现完美符合本题,于是我们考虑使用数位dp来解决这道题

本题解使用的是记忆化搜索的方式(其实是不会递推写法喵)


状态设计

看到洛谷题解区的大佬好像很多都是用一维表示0和1的个数的差,也有没有在dp数组中存储前导0的大佬,那样貌似空间小一些。但是我太菜了,一开始都没想到,于是用了两维分别表示0和1的个数。

\[dp_{{cnt},{sum0},{sum1},{qd}} \]

这个表示:枚举到第cnt位,0的总数为sum0,1的总数为sum1,前面的每一位数是不是都是前导0,的数有多少个。(当qd=1时表示前面数都是前导0,qd=0时则表示前面数不是都是前导0)


前导0

关于为什么要看前面的每一位数是不是都是前导0:
因为如果不判断前导0的话,类似于 $ 00100 $ 这样的数的前面的0本来是不应该统计的,但不判断前导零时则会被统计进sum0中去。所以一定要看前导零。


tips:

1.因为这个题的数据范围只有2e9,所以不用开long long。
2.在2进制中2e9有30位(貌似),主包一开始开小了(只有我会这样吧)
3.主包写代码写一半忘记是2进制了,怒调两分半。
4.记得初始化


代码:

#include<bits/stdc++.h>
using namespace std;
int l,r;
const int MAXN=35;
int a[MAXN];//十进制的数拆分成2进制每一位是什么 
int dp[MAXN][MAXN][MAXN][2];//枚举到第i位,有j个0,k个1,前面是不是都是前导0的数的个数 
int dfs(int cnt,int flag,int sum0,int sum1,int qd){
//cnt:枚举到了cnt位,flag:这一位有没有限制,其他的看上文:P 
	if(qd){//如果前面全都是前导0,那么这些0都不能算进0的总个数中 
		sum0=0;
	}
//下面的就是数位dp经典模板了(划掉 
	if(!cnt){
		if(sum0>=sum1){
			return 1;
		}
		return 0;
	}
	if(!flag && ~dp[cnt][sum0][sum1][qd]){
		return dp[cnt][sum0][sum1][qd];
	}
	int maxi=a[cnt];
	if(!flag){
		maxi=1;
	}
	int ret=0;
	for(int i=0;i<=maxi;i++){
		ret+=dfs(cnt-1,flag&&(i==maxi),sum0+(i==0),sum1+(i==1),qd&&(i==0));
	}
	if(!flag){
		return dp[cnt][sum0][sum1][qd]=ret;
	}
	return ret;
} 
int query(int x){
	int cnt=0;
	while(x){
		cnt++;
		a[cnt]=x&1;
		x>>=1;
	}
	return dfs(cnt,1,0,0,1);//从最后一位开始,有限制,0和1的个数都是0,有前导零 
}
int main(){
	cin>>l>>r;
	memset(dp,-1,sizeof(dp));
	cout<<query(r)-query(l-1);	
}

结语

煮包的通过记录

呃呃,真的写不动题了啊啊,只能来水题解了。(吐血

我的洛谷(魂兮归来......

标签:cnt,int,题解,sum0,qd,USACO06NOV,前导,Round,dp
From: https://www.cnblogs.com/Le-Louvre/p/18367710

相关文章

  • [题解]UVA1127 Word Puzzles
    UVA1127WordPuzzles我们对模式串建立AC自动机,然后就比较板子了,只需要把\(8\)个方向都跑一遍匹配就可以了。时间复杂度是\(O(T\times8nm)\)。注意输入是大写字母。点击查看代码#include<bits/stdc++.h>#defineK1010//模式串个数&矩阵长宽#defineN1000010//节点个......
  • el-table使用sortablejs推拽排序卡顿问题解决
    使用sortablejs拖拽el-table排序时,对于纯文本表格,正常使用即可,不会卡顿initSort(){consttbody=document.querySelector('.el-table__body-wrappertbody')const_this=thisSortable.create(tbody,{draggable:'.el-table__row',......
  • 【题解】Solution Set - NOIP2024集训Day10 树的直径、重⼼、中⼼
    【题解】SolutionSet-NOIP2024集训Day10树的直径、重⼼、中⼼https://www.becoder.com.cn/contest/5464「CF516D」DrazilandMorningExercise首先,我们可以换根求出所有点的\(f\)。然后不会了……思考一下,一条直径提供的到底时什么。实际上,一条直径上的点取到\(f\)......
  • Vue 项目报错Uncaught SyntaxError: Unexpected token < 刷新之后又可以继续访问问题解
    场景:页面打开不操作,前端项目代码更新重新部署后(比如Jenkins发布部署)页面不刷新,操作页面(点击打开弹窗、切换菜单等),页面没有反应,控制台报错 UncaughtSyntaxError:Unexpectedtoken<。这个问题偶现,只有在项目重新部署后会出现,页面刷新后就恢复正常 问题原因:在前端项目未更......
  • 题解:牛客周赛 Round 56(A-E)
    A面包店故事题面小镇上有一家面包店,面包以\(x\)元的价格出售,加\(y\)元可以多加几块培根。小歪带着\(n\)元来到了面包店,他想知道自己能不能买到加培根的面包?输入在一行上输入三个整数\(x,y,n\left(1\lex,y,n\le100\right)\)代表面包的价格、培根的价格和小歪带的......
  • P1540 [NOIP2010 提高组] 机器翻译 题解
    题目概括给定N个整数,和一个容量为M的“字典”,从头到尾依次翻译,每次翻译先看自家字典,没有的话再看别人的字典并存到自家字典,如果自家字典满了,当前单词的翻译会代替最早进入的。做题思路定义一个长度为M的字典数组,依次遍历N个数,每次翻译先检索字典数组,没有的话加入字典并......
  • 题解:P10844 [EGOI2024] Infinite Race / 无限赛跑
    题解:P10844[EGOI2024]InfiniteRace/无限赛跑有n个人在环形跑道上跑步,和q次超越别人或被别人超越,别人要么在Anika前面,要么在后面怎么说呢,建议降红由于只有重复超过一个人才肯定是跑过一圈的,所以一个数组就行了,每超过一次就打上标记,不然去掉标记。#include<bits/stdc......
  • 题解:AT_iroha2019_day1_f Head of The Dragon
    题目大意得知\(n\)和\(k\),求出\(n\)是否能分解出\(k\)个因数相乘,输出按字典序最小一种情况。步骤将\(n\)分解质因数。判断质因数个数是大于\(k\),否则输出\(-1\)。按照分解出来的质因数从小到大输出。代码#include<bits/stdc++.h>#defineintlonglongus......
  • 牛客周赛 Round 56
    牛客周赛Round56\(A\)牛客NC277678面包店故事\(AC\)选择结构。点击查看代码intmain(){intx,y,n;cin>>x>>y>>n;if(x+y<=n){cout<<"YES"<<endl;}else{cout<<"NO&qu......
  • Big Clique Everywhere 题解
    给个链接:BigCliqueEverywhere。先说一下团(clique)是什么,其实就是完全图。考虑什么情况下不满足题意。我们可以先建出补图,下面的东西都在补图中完成。我们首先给出结论:如果该图中有奇环(不是二分图),则条件不成立,否则成立。这里证明一下:如果存在奇环,则把点集设为这个奇环中的点,那......