【算法竞赛】状态压缩型背包问题经典应用(蓝桥杯2019A4分糖果)
在蓝桥杯中遇到的这道题,看上去比较普通,但其实蕴含了很巧妙的“状态压缩 + 背包”的思想,本文将从零到一,详细解析这个问题。
目录
一、题目
二、思路分析:状态压缩 + 最小覆盖
1. 本质:最小集合覆盖问题
2. 状态设计:压缩子集状态
3. 状态转移逻辑
4. 为什么不用回溯解决?
三、状压DP通用压缩和转移技巧
1. 应用场景
2. 状压DP的核心构建思维
3. 状态遍历技巧
四、代码
五、关键点总结
一、题目
4.糖果 - 蓝桥云课
【翻译过来就是】:
店里有 M
种不同口味的糖果。老板不单卖糖果,而是将 K
颗糖果打包成一包,并且每包糖果的口味可以预知。小明希望通过购买若干包糖果,品尝到所有 M
种口味
我们的目标是:求出小明最少要买多少包糖果,才能尝到所有口味?
若无论如何都无法凑齐所有口味,输出 -1
二、思路分析:状态压缩 + 最小覆盖
1. 本质:最小集合覆盖问题
这道题本质上是一个最小集合覆盖问题:
给定
M
个元素的全集,每个集合(糖果包)覆盖部分元素,求用最少的集合数量,使得它们的并集恰好覆盖全集。
这类问题是组合优化中非常典型的 NP 完全问题,而这道题因为数据规模小(M ≤ 20
),我们可以用状态压缩优化搜索空间
2. 状态设计:压缩子集状态
考虑全集是口味 {1, 2, ..., M}
,那么每种“已经吃到的口味组合”可以表示为一个二进制串,长度为 M
:
-
第
i
位为1
表示第i
种口味已吃; -
第
i
位为0
表示第i
种口味未吃; -
例如
01101
表示尝到了第 0、2、3 种口味。
于是我们就可以设计出如下的状态压缩动态规划:
-
状态定义:
dp[s]
表示要想吃到状态s
表示的口味集合,最少要买多少包糖果; -
状态个数:全集口味数为
M
,所以一共有2^M
个状态; -
初始状态:
dp[0] = 0
表示什么都没吃; -
最终目标:我们要找出
dp[full]
,其中full=(1<<M)-1
,即全1,代表吃全所有口味
3. 状态转移逻辑
我们遍历每一包糖果(相当于“可以选的物品”),如果当前状态是 j
,那么加入这一包糖果之后,会变成新状态 j|a[i]
转移公式如下:
dp[j|a[i]] = min(dp[j|a[i]], dp[j]+ 1)
意思是:“如果我当前吃到的是状态j
,现在加上这包糖果 a[i]
,我就能达到一个新的状态j |a[i],
那到达新状态的最小糖果包数,可能是之前状态的基础上+1
为了避免状态转移时污染原始状态(避免用新的 dp[j|a[i]]
去影响其它转移),我们从大到小遍历状态 j
4. 为什么不用回溯解决?
很多读者第一时间可能想到回溯 + 剪枝,但那样复杂度是指数级的
这题可以用动态规划,是因为:
-
状态可以表示为一个整数,并且状态间的转移有明显结构;
-
每一步的选择(糖果包)都可以使得状态“合并”;
-
我们可以用子问题的最优解构造出大问题的最优解,符合DP的子结构性质。
三、状压DP通用压缩和转移技巧
状态压缩 DP是竞赛算法中经常考的一种技巧,尤其当状态具有“组合”性质时非常常见
1. 应用场景
-
集合覆盖类问题(如本题)
-
旅行商问题(TSP)
-
开关灯问题 / 翻牌问题
-
博弈论中已访问节点记录
-
图上路径问题中“走过哪些点”状态的保存
2. 状压DP的核心构建思维
-
状态压缩:
-
使用一个整数的二进制表示“某种集合”
-
长度为
M
的集合有2^M
个子集,对应0~2^M - 1
这2^M
个整数
-
-
状态定义:
-
每一个状态代表一种“中间形态”,可以是路径、集合、排列的某种子结构
-
dp[mask]
表示从起点出发,达到状态mask
所需要的最小代价/方案数等
-
-
状态转移:
-
通常通过
dp[old_mask]->dp[new_mask]
来实现 -
new_mask=old_mask|(1<<x)
表示在old_mask
的基础上加入一个新元素 -
利用位运算快速合并和判断状态(如:是否包含、是否重叠等)
-
3. 状态遍历技巧
接下来给大家附上一下状态压缩常用的小技巧
遍历目标 | 写法 |
---|---|
遍历所有状态 | for (int mask = 0; mask < (1 << M); mask++) |
遍历 mask 的所有子集 | for (int sub = mask; sub; sub = (sub - 1) & mask) |
检查 mask 是否包含第 i 项 | if (mask & (1 << i)) |
加入元素 i | mask | (1 << i) |
删除元素 i | mask & ~(1 << i) |
四、代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <climits>
using namespace std;
long long dp[(1<<20)+1];//左移20位
int n,m,k;
int a[110];//第i包所有的种类
int main()
{fill(dp,dp+(1<<20)+1,INT_MAX);//初始化为最大值cin>>n>>m>>k;//n包糖果,m种口味,每包k种int c[25];//占位数组,是否能全部尝到fill(c,c+m,0);bool no=false;//是否能全部尝到//读入n包糖果for(int i=1;i<=n;i++){int x=0,y;for(int j=1;j<=k;j++){cin>>y;//转换为二进制//(1后面有y-1个0,相当于第y位是1) y--;x|=(1<<y); //先检验糖果是否全 //索引向后移一位 c[y]++;}a[i]=x;} //首先检验糖果种类是否齐全for(int i=0;i<m;i++){if(!c[i]) no=true;} if(no) cout<<"-1";else{//背包问题,装i包糖果使每一种口味都能尝到 dp[0]=0;//遍历每一包 for(int i=1;i<=n;i++){//状态从大到小 //背包问题,滚动数组背包容量从大到小 for(int j=(1<<m)-1;j>=0;j--){//是否选第i包 dp[j|a[i]]=min(dp[j|a[i]],dp[j]+1);}}//0-m-1位都为1 cout<<dp[(1<<m)-1];}return 0;
}
五、关键点总结
技巧 | 说明 |
---|---|
状态压缩 | 将口味组合转换为一个整数表示 |
背包状态转移 | dp[new_state] = min(dp[new_state], dp[old_state] + 1) |
滚动数组优化 | 状态转移从大到小,避免重复选择 |
初始化技巧 | INT_MAX 代表当前状态不可达,一定要用 long long 存储,否则可能溢出 |
这个问题很好的考察了对“状态压缩 + 背包模型”的掌握,也是一道蓝桥杯常考的“最小覆盖子集”变形题,可以作为一道练手题
如果你觉得本文对你有帮助,欢迎点赞收藏!
相关文章:
【算法竞赛】状态压缩型背包问题经典应用(蓝桥杯2019A4分糖果)
在蓝桥杯中遇到的这道题,看上去比较普通,但其实蕴含了很巧妙的“状态压缩 背包”的思想,本文将从零到一,详细解析这个问题。 目录 一、题目 二、思路分析:状态压缩 最小覆盖 1. 本质:最小集合覆盖问题…...
【C++初阶篇】C++中c_str函数的全面解析
C中c_str函数的全面解析 1. c_str()函数的定义与原型2. c_str()函数的返回值特性3 c_str()函数的使用场景3.1 与C标准库函数交互3.2 文件操作3.3 系统调用 4. c_str()函数的注意事项4.1 返回指针的只读性4.2 生命周期问题4.3 空字符串处理4.4 避免直接赋值给char* 5. c_str()函…...
Python 匿名函数(Lambda函数)
什么是匿名函数 匿名函数(也称为lambda函数)是Python中的一种小型匿名函数,它可以接受任意数量的参数,但只能有一个表达式。 语法格式: lambda arguments: expression使用场景 简单函数逻辑:当函数逻辑…...
java高并发------守护线程Daemon Thread
文章目录 1.概念2.生命周期与行为2. 应用场景3. 示例代码4. 注意事项 1.概念 Daemon : 滴门 在Java中,线程分为两类:用户线程(User Thread)和守护线程(Daemon Thread)。 守护线程是后台线程,主要服务于用户线程,当所…...
RocketMQ初认识
ProducerCustomerNameServer: Broker的注册服务发现中心BrokerServer:主要负责消息的存储、投递和查询以及服务高可用保证 RocketMQ的集群部署: 单个master的分支多个Master 模式:集群中有多个 Master 节点,彼此之间相互独立。生产者可以将消…...
K8s的BackUP备份
文章目录 1、kubeadm 安装的单 master 节点数据备份和恢复方式2、Velero 工具3、Velero 服务部署4、备份还原数据 ETCD备份/还原有多种类型,取决于你 k8s 集群的搭建方式 1、kubeadm 安装的单 master 节点数据备份和恢复方式 拷贝 etcdctl 至 master 节点…...
Photoshop 快捷键指南
Photoshop 快捷键指南 放大缩小 按住 Ctrl 鼠标滚轮快捷键 Z 鼠标左键往左往右Ctrl 放大, Ctrl - 缩小 套索工具 快捷键 L鼠标左键绘制按住 ctrl,松开鼠标左键,继续绘制直线绘制完成之后,按住ctrl,鼠标左键继续绘…...
Openlayers:海量图形渲染之图片渲染
最近由于在工作中涉及到了海量图形渲染的问题,因此我开始研究相关的解决方案。在这个过程中我阅读了文章 《Openlayers海量矢量面渲染优化》了解到了利用Canvas在前端生成图片渲染的思路,后来我又从同事那里了解到了后端生成图片渲染的思路。我认为这两种…...
自定义组件触发饿了么表单校验
饿了么的表单控件,如果存在自定义组件更改了值,例如在el-from中存在原生input组件很有可能没法触发表单校验,下拉框或者弹框组件仍然是报红边框。 这是因为饿了么的输入框或者下拉框更改值的时候会自动触发表单校验,但是封装过后的…...
【C++】从零实现Json-Rpc框架(1)
目录 一、项目介绍 二、技术选型 1. RPC的实现方案: 2. 网络传输的参数和返回值怎么映射到对应的RPC 接口上? 3. 网络传输怎么做? 4. 序列化和反序列化? 三、开发环境 四、环境搭建 Ubuntu-22.04 环境搭建 项目汇总&…...
[实战] linux驱动框架与驱动开发实战
linux驱动框架与驱动开发实战 Linux驱动框架与驱动开发实战一、Linux驱动框架概述1.1 Linux驱动的分类1.2 Linux驱动的基本框架 二、Linux驱动关键API详解2.1 模块相关API2.2 字符设备驱动API2.3 内存管理API2.4 中断处理API2.5 PCI设备驱动API 三、Xilinx XDMA驱动开发详解3.1…...
【详细】MySQL 8 安装解压即用 (包含MySQL 5 卸载)
卸载MySQL 1.卸载 2.安装目录删除残余文件(当初安装的位置) 3.删除programData下面的mysql数据文件 4.检查mysql服务是否存在,如果存在则删除(先暂停mysql服务) sc delete mysql 5.删除注册表中残留信息 安装MySQL 8&…...
Linux:(五种IO模型)
目录 一、对IO的重新认识 二、IO的五种模型 1.阻塞IO 2.非阻塞IO 3.信号驱动IO 4.IO多路转接 5.异步IO 6.一些概念的解释 三、非阻塞IO的代码实现 1.fcntl 2.实现主程序 一、对IO的重新认识 如果有人问你IO是什么,你该怎么回答呢? 你可能会说…...
初识数据结构——Java包装类与泛型:从入门到源码解析
【深入浅出】Java包装类与泛型:从入门到源码解析 🌟 一、开篇一问:为什么我们需要包装类? Java作为一门"面向对象"的语言,却保留了8个"非对象"的基本数据类型(有传言说,是…...
【计算机网络】Linux配置SNAT策略
什么是NAT? NAT 全称是 Network Address Translation(网络地址转换),是一个用来在多个设备共享一个公网 IP上网的技术。 NAT 的核心作用:将一个网络中的私有 IP 地址,转换为公网 IP 地址,从而…...
与 AI 共舞:解锁自我提升的无限可能
与 AI 共舞:解锁自我提升的无限可能 在数字化浪潮的汹涌冲击下,人工智能(AI)正以前所未有的速度重塑着世界的每一个角落。从日常生活的点滴便利到复杂工作的高效推进,AI 的力量无处不在。然而,面对 AI 的强…...
Android学习总结之算法篇五(字符串)
字符串求回文字串数目 public class CountPalindromicSubstrings {/*** 此方法用于计算字符串中回文子串的数量* param s 输入的字符串* return 回文子串的数量*/public static int countSubstrings(String s) {// 若输入字符串为空或长度为 0,直接返回 0if (s nu…...
使用人车关系核验API快速核验车辆一致性
一、 引言 随着车辆交易的日益频繁,二手车市场和金融领域的汽车抵押业务蓬勃发展。然而,欺诈和盗窃行为也时有发生,给行业带来了不小的冲击。例如,3月20日央视曝光的“新能源车虚假租赁骗补”产业链,以及某共享汽车平…...
day 8 TIM定时器
一、STM32 定时器概述 1. 定时器的概述定时器的基本功能,但是 STM32 的定时器除了具有定时功能之外,也具有定时器中断功能,还具有输入捕获(检测外部信号)以及输出比较功能(输出不同的脉冲)&…...
硬币找零问题
硬币找零问题:假设需要找零的金额为C,最少要用多少面值为p1<p2<…<pn的硬币(面值种类为n,且假设每种面值的硬币都足够多)? 贪心算法的基本原理是:遵循某种既定原则,不断…...
【微机及接口技术】- 第四章 内部存储器及其接口(上)
文章目录 第一节一、存储器的分类二、存储器的层次结构 第二节 半导体存储器一、半导体存储器的基本结构二、半导体存储器的分类1. 只读存储器 ROM2. 随机存储器 RAM 三、内存的主要性能指标1. 存储容量2. 存取时间3. 存取周期4. 可靠性5. 性价比 四、典型的半导体存储器芯片 本…...
tomcat的web三大组件Sciidea搭建web/maven的tomcat项目
文章目录 1. web项目的搭建1. 创建web项目2.修改web.xml版本3.添加servlet、jsp依赖4.servlet示例(使用注解)5.配置tomcat6.添加artifact7.部署8.启动tomcat、访问9.打war包10.部署到tomcat 2.maven的项目搭建1.创建项目图解 2.tomcat启动方式图解idea打…...
《SQL赋能人工智能:解锁特征工程的隐秘力量》
在当今的科技发展进程中,人工智能(AI)已经成为推动各领域变革的核心驱动力。而在人工智能的庞大体系里,特征工程占据着举足轻重的地位,它是将原始数据转化为能够让模型有效学习的特征的关键环节。鲜有人深入探讨的是&a…...
SQLmap工具使用
1. sqlmap介绍 sqlmap是一款自动化的SQL注入工具,用于检测和利用web应用程序中的SQL注入漏洞。不需要我们进行手注,当我们输入url地址后,会自动进行注入指令并将payload返回显示。 在kali中自带。在本机中需要下载,在相应的路径…...
Kubernetes集群管理详解:从入门到精通
1. 引言 Kubernetes(简称k8s)作为当今最流行的容器编排平台,已成为云原生应用部署和管理的事实标准。本文将深入探讨k8s集群管理的各个方面,为运维工程师和开发人员提供一个全面的指南。 2. Kubernetes架构概览 在深入具体的管理任务之前,让我们先回顾一下Kubernetes的基本架…...
【含文档+PPT+源码】基于Python的全国景区数据分析以及可视化实现
项目介绍 本课程演示的是一款基于Python的全国景区数据分析以及可视化实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 带你从零开始部署运行本套系统 该…...
鸿蒙开发者高级认证编程题库
题目一:跨设备分布式数据同步 需求描述 开发一个分布式待办事项应用,要求: 手机与平板登录同一华为账号时,自动同步任务列表任一设备修改任务状态(完成/删除),另一设备实时更新任务数据在设备离线时能本地存储,联网后自动同步实现方案 // 1. 定义分布式数据模型 imp…...
【网络安全】安全的网络设计
网络设计是网络安全的基础,一个好的网络设计可以有效的防止攻击者的入侵。在本篇文章中,我们将详细介绍如何设计一个安全的网络,包括网络架构,网络设备,网络策略,以及如何处理网络安全事件。 一、网络架构…...
基于FLask的重庆市造价工程信息数据可视化分析系统
【FLask】基于FLask的重庆市造价工程信息数据可视化分析系统 (完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 在当今快速发展的建筑工程行业中,造价信息的准确性和时效性对于项目决…...
swift-08-属性、汇编分析inout本质
一、Swift中跟实例相关的属性可以分为2大类 1.1 存储属性( Stored Property) 类似于成员变量这个概念 存储在实例的内存中 结构体、类可以定义存储属性 枚举不可以定义存储属性(因为枚举只存储关联值和case) 1.2 计算属性&am…...
Java 大视界 -- Java 大数据在智能医疗远程护理与患者健康管理中的应用与前景(175)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
大数据技术发展与应用趋势分析
大数据技术发展与应用趋势分析 文章目录 大数据技术发展与应用趋势分析1. 大数据概述2 大数据技术架构2.1 数据采集层2.2 数据存储层2.3 数据处理层2.4 数据分析层 3 大数据发展趋势3.1 AI驱动的分析与自动化3.2 隐私保护分析技术3.3 混合云架构的普及3.4 数据网格架构3.5 量子…...
如何在Ubuntu上安装Dify
如何在Ubuntu上安装Dify 如何在Ubuntu上安装docker 使用apt安装 # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg…...
ffmpeg音频分析
对一个16k 单声道音频,生成频谱图 ./ffmpeg -i input.wav -lavfi "showspectrumpics800x400:modecombined:scalelin:gain1.5" spectrum.png...
每天五分钟深度学习框架pytorch:搭建LSTM完成手写字体识别任务?
本文重点 前面我们学习了LSTM的搭建,我们也学习过很多卷积神经网络关于手写字体的识别,本文我们使用LSTM来完成手写字体的识别。 网络模型的搭建 class RNN(nn.Module):def __init__(self,in_dim,hidden_dim,n_layer,n_class):super(RNN,self).__init__()self.n_layer=n_la…...
Maven工具学习使用(七)——Maven属性
内置属性 主要有两个常用的属性${basedir}表示项目的根目录,即包含pom.xml文件的目录;$[version]表示项目版本。 POM属性 使用该类属性引用POM文件中对应元素的值。例如${project.artifactId}就对应了元素的值,常用的POM属性包括: ${project.build.sourceDirectory} 项…...
【Linux网络与网络编程】05.应用层自定义协议序列化和反序列化
前言 本篇博客通过网络计算器的实现来帮助各位理解应用层自定义协议以及序列化和反序列化。 一、认识自定义协议&&序列化和反序列化 我们程序员写的一个个解决我们实际问题,满足我们日常需求的网络程序都是在应用层。前面我们说到:协议是一种…...
搭建K8S-1.23
0、简介 这里只用3台服务器来做一个简单的集群 地址主机名192.168.160.40kuber-master-1192.168.160.41kuber-master-2192.168.160.42kuber-node-1 1、关闭三个服务 (1)防火墙 systemctl stop firewalld (2)Selinux setenf…...
解决Spring Boot Test中的ByteBuddy类缺失问题
目录 解决Spring Boot Test中的ByteBuddy类缺失问题前奏问题描述问题解决第一步:移除ByteBuddy的特定版本号第二步:更新maven-surefire-plugin配置第三步:清理并重新构建项目 结语 解决Spring Boot Test中的ByteBuddy类缺失问题 前奏 今天&…...
npm 项目命名规则
以下是 npm 项目命名规则的详细说明: 一、核心命名规则 必须使用小写字母 名称中不能包含大写字母。原因: 跨平台兼容性(如 Linux 区分大小写,而 Windows 不区分)。避免命令行和 URL 中的大小写冲突(例如包…...
#SVA语法滴水穿石# (012)关于 first_match、throughout、within 的用法
我们今天学习, SystemVerilog 断言(SVA)中 first_match、throughout、within 运算符。 1. first_match 定义与作用 功能:在可能产生 多个匹配结果 的复合序列(如 or 或重复操作符)中,仅选择第…...
基于springboot+vue的二手车交易系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
洛谷P11999.投入严厉地本地
洛谷P11999.投入严厉地本地 题目 题目解析及思路 题目要求根据两个字符串s和t,反推出一个映射集合f,其中s的每一个长度为k的子串都可以映射成单个字符或空字符 算出最终映射集合有多少个空字符,用全排列函数去搜索所有情况,判断…...
低代码开发平台:飞帆中新增控件、修改他人控件
飞帆是一个自由的控件平台。所有的网页都由控件搭建而成。 在我的资源、我的控件中,点击新增可以新增控件 对于他人的控件,点击复制控件展开,点击复制到我的控件 飞帆中的控件是使用 Vue2 来实现的...
Openstack指南
什么是云计算 概念 云计算是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息,可以按需求提供给计算机和其他设备。用户不需要了解”云“中的基础设施细节,不必具有相应的专业知识,也无需直接控制。云…...
[自制调试工具]构建高效调试利器:Debugger 类详解
一、引言 在软件开发的漫漫征程中,调试就像是一位忠诚的伙伴,时刻陪伴着开发者解决代码里的各类问题。为了能更清晰地了解程序运行时变量的状态,我们常常需要输出各种变量的值。而 Debugger 类就像是一个贴心的调试助手,它能帮我…...
【网络IP】原生IP是什么?如何获取海外原生IP?
一、什么是原生IP 原生IP地址是互联网服务提供商(ISP)直接分配给用户的真实IP地址,无需代理或转发。这类IP的注册国家与IP所在服务器的注册地相符。这种IP地址直接与用户的设备或网络关联,不会被任何中间服务器或代理转发或隐藏。…...
【小沐学Web3D】three.js 加载三维模型(React Three Fiber)
文章目录 1、简介1.1 Three.js1.2 React Three Fiber 2、测试2.1 初始化环境2.2 app.js修改(显示内置立方体)2.3 app.js修改(显示内置球体)2.4 app.js修改(显示自定义立方体)2.5 app.js修改(显示…...
HTTP查询参数示例(XMLHttpRequest查询参数)(带查询参数的HTTP接口示例——以python flask接口为例)flask查询接口
文章目录 HTTP查询参数请求示例接口文档——获取城市列表代码示例效果 带查询参数的HTTP接口示例——以python flask接口为例app.pyREADME.md运行应用API示例客户端示例关键实现说明:运行方法: HTTP查询参数请求示例 接口文档——获取城市列表 代码示例…...
【玩泰山派】1、mac上使用串口连接泰山派
文章目录 前言picocom工具连接泰山派安装picocom工具安装ch340的驱动串口工具接线使用picocom连接泰山派 参考 前言 windows上面有xshell这个好用的工具可以使用串口连接板子,在mac上好像没找到太好的工具,只能使用命令行工具去搞了。 之前查找说mac上…...