首页 > 其他分享 >Bitset容器与优化

Bitset容器与优化

时间:2024-10-26 10:52:10浏览次数:8  
标签:容器 bit1 硬币 int Bit1 Bitset 优化 dp bitset

Bitset是啥

某种神奇的容器,用于存储二进制。头文件:

#include<bitset>

定义方法:

bitset<5> Bit1("10011");
bitset<5> Bit2(4);

“<>” 中的内容代表容器的长度,相当于一个数组,但是每一位只能存储 0 0 0 或 1 1 1,所以每一位占用 1 1 1 bit 的内存。赋值方法分两种,一种像字符串一样的,会直接把这一串数字存入。一种是填入一个数值,会把这个数转成二进制存储。
喜欢作的人(比如说我)肯定会问:
那么如果我存的数超过了设定的位数会怎么样?
在这里插入图片描述
这个时候,我们发现两种复制方法用了不同的方式处理。第一种取了最左边的 5 5 5 位,第二种取了最右边的 5 5 5 位。但是它们都不会报错。补充一下如果存入的位数不足,会用前导零填充。
如果我输入了一个非 0 / 1 0/1 0/1 的串,会怎么样?

bitset<5> Bit1("534");

这么玩的话会报错。

Bitset的运用

我们再来玩点花的。首先要讲解一下数组用法,数组是从最右侧开始的。

bitset<5> Bit1;
Bit1[0]=1;

此时 Bit1 里面是 00001
接下来就逐渐神奇了,先拿出一道很简单的题。
给你 n n n 种硬币,面值分别是 a i a_i ai​,每种硬币有 c i c_i ci​ 个,问你买一个价值为 m m m 的物品,能否在不找零的情况下购买?
首先想到背包,用 d p i , j dp_{i,j} dpi,j​ 表示用到了第 i i i 种硬币,能否凑出价值为 j j j 的钱。由于内存可能会不够,所以我们压掉一维,但注意这里的循环要倒过来。

#include<bits/stdc++.h>
using namespace std;
int n,m,a[105],c[105];
bool dp[100005];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i]>>c[i];
	dp[0]=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=c[i];j++)
			for(int k=m;k>=a[i];k--)
				dp[k]|=dp[k-a[i]];
	cout<<dp[m]<<endl;
	return 0;
}

可是这跟 bitset 有啥关系?注意到 d p dp dp 里的值都是 0 / 1 0/1 0/1,可以直接变成 bitset,这样还能省掉循环。
在这里插入图片描述
首先我们先分析一下这些 1 1 1 是从哪里来的。假设当前硬币面值为 6 6 6,有两种情况,一种是从上面对应的位置继承(不使用这个硬币),一种是从往前数第 6 6 6 个位置继承(使用这个硬币)。如果我们把第一行的 1101000100010 存入 bitset,称为 bit1,那么第二行的 bit2 就是原本的 bit1 按位或 bit1>>6bit1>>6 就将原本的位置 3 3 3 移到了位置 6 6 6,是正确的。而且此时所有操作是同时做的,不用担心要倒着循环。关键是,它特别适合卡常,在一个长度为 n n n 的 bitset 上进行操作只需要 n 32 \frac{n}{32} 32n​ 的时间复杂度。好了,先写程序练手吧。

#include<bits/stdc++.h>
using namespace std;
int n,m,a[105],c[105];
bitset<15> dp;
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i]>>c[i];
	dp[0]=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=c[i];j++)
			dp=dp|(dp<<a[i]);
	cout<<dp[m]<<endl;
	return 0;
}

如果你真的按照上述写就完了,注意 bitset 的数组是倒着存的,所以应当是 <<a[i]
第二种运用后续更新哦。

标签:容器,bit1,硬币,int,Bit1,Bitset,优化,dp,bitset
From: https://blog.csdn.net/2401_84512298/article/details/143193303

相关文章

  • 鸿蒙编程江湖:ArkTS 容器与原生容器在行为上的差异
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。ArkTS提供了一套容器集,包括Array、Map......
  • 鸿蒙案例实践:图像处理应用中多线程任务调度与性能优化
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。1.项目需求与目标分析背景:图像处理......
  • 短视频app开发源码,骨架屏技术优化前端体验
    一、什么是骨架屏?骨架屏是一种在短视频app开发源码页面加载过程中,以占位符形式展示页面结构的技术。它通过显示简单的灰色块和线条,让用户在等待内容加载时获得视觉反馈,提高了用户的满意度。二、为什么需要骨架屏?在移动设备和慢速网络环境下,短视频app开发源码的页面加载速度变得......
  • Cocos Creator引擎开发:Cocos Creator基础入门_CocosCreator性能优化
    CocosCreator性能优化1.渲染优化1.1减少DrawCall在CocosCreator中,DrawCall是影响渲染性能的一个重要因素。每个DrawCall都会导致GPU和CPU之间的数据传输,因此减少DrawCall的数量可以显著提高游戏的渲染性能。原理DrawCall是指从CPU向GPU发送渲染指令的过程。每......
  • 深度解读:PostgreSQL执行计划的高效优化指南
    全文目录:开篇语前言:为何要解读PostgreSQL执行计划?......
  • 基于贝叶斯优化卷积神经网络(Bayes-CNN)的多因子数据分类识别算法matlab仿真
    1.算法运行效果图预览(完整程序运行后无水印) 贝叶斯优化过程  贝叶斯优化后的CNN训练和识别结果 标准的CNN的识别结果 2.算法运行软件版本matlab2022a 3.部分核心程序(完整版代码包含详细中文注释和操作步骤视频)%使用贝叶斯优化算法确定最优的批......
  • 一种巧妙的DP优化方法——pht转化
    P6944[ICPC2018WF]GemIsland之前一直都没有弄懂pht转化有什么用,现在懂了,故作文以记之。直接从CYJ的题解开始讲起,这种阶梯DP是人都想得出来,只不过是\(O(n^4)\)或者\(O(n^3ln(n))\)的,本人觉得这道题的关键在于如何优化掉整整一个\(O(n)\)首先一个数列的权值就是类似于......
  • 巧妙的dp优化方法
    \(\color{green}\textbf{[记录一种巧妙的dp优化方法]}\)这是一种巧妙的优化状态的方法,通过把状态提前(或者说是把状态转化为限制)的方法来避免记录一些别的信息,这种优化方法相比起数据结构优化更加强大,故作文记之\(\color{blue}\textbf{[例题]}\)CF1679ETypicalPartyinDorm......
  • 如何进行多线程优化?
    为了提高程序的运行效率,多线程优化成为了一种重要的方法。本文将详细指导你如何进行多线程优化:1.识别并行化机会;2.保证线程安全;3.选择正确的并发工具;4.避免死锁和竞态条件;5.优化线程间的通信。为了成功地实施多线程优化,首先需要了解程序的瓶颈所在。1.识别并行化机会在程序中,......
  • 【c++篇】:解析c++类--优化编程的关键所在(三)
    感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢个人主页:余辉zmh–CSDN博客文章所属专栏:c++篇–CSDN博客文章目录一.构造函数的初始化列表1.1构造函数体的赋值1.2初始化列表1.3`explicit`关键字二.静态`static`成员2.1.静态成员变量......