每日c/c++题 备战蓝桥杯(修理牛棚 Barn Repair)

修理牛棚 Barn Repair 题解

问题背景与挑战

在一个暴风雨交加的夜晚,Farmer John 的牛棚遭受了严重的破坏。屋顶被掀飞,大门也不翼而飞。幸运的是,许多牛正在度假,牛棚并未住满。然而,为了保护那些还在牛棚里的牛,Farmer John 必须尽快用木板修复牛棚。但是,他的木材供应商是一个吝啬鬼,只能提供有限数量的木板。为了避免浪费资源,Farmer John 希望以最少的木板总长度覆盖所有有牛的牛棚。这是一个典型的优化问题,我们需要在资源有限的情况下,找到最优的解决方案。

输入输出格式详解

输入

输入数据包含两部分:

  • 第一行包含三个整数 msc,分别表示木板的最大数目、牛棚的总数以及牛的总数。
  • 接下来 c 行,每行包含一个整数,表示牛所在的牛棚编号。

输出

输出一个整数,表示覆盖所有有牛的牛棚所需的最小木板总长度。

问题分析与思路探索

这道题是一个典型的区间覆盖问题。我们需要用有限的木板覆盖所有有牛的牛棚,同时使木板的总长度最小。这就好比在一条数轴上,有若干个点(牛棚编号),我们的任务是选择若干个区间(木板的覆盖范围),使这些区间的总长度最短。

我最初的想法是直接暴力枚举所有可能的覆盖方式,但很快意识到这种方法的局限性。随着牛棚数量和木板数量的增加,暴力搜索的时间复杂度呈指数级增长,根本无法在合理的时间内解决问题。于是,我开始思考如何利用动态规划(Dynamic Programming,DP)来优化这个问题。

动态规划是一种将复杂问题分解为简单子问题的算法思想。它通过存储子问题的解,避免重复计算,从而大大提高算法效率。在这个问题中,我们可以定义一个二维数组 f[i][j],表示用 j 块木板覆盖前 i 个牛棚的最小总长度。通过对子问题的逐步求解,我们可以最终得到全局最优解。

动态规划的思路与状态转移方程

动态规划表的定义

我们定义 f[i][j] 表示用 j 块木板覆盖前 i 个牛棚的最小总长度。这是一个二维数组,其中 i 表示牛棚的编号,j 表示使用的木板数量。

状态转移方程的推导

对于每个牛棚 i 和木板数目 j,我们有两种选择:

  1. 放置新的木板:如果在当前牛棚 i 处放置一块新的木板,那么总长度将增加 1(因为每个牛棚的宽度相同),并且使用的木板数量增加 1。这种情况下,状态转移方程为:
    f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] + 1 f[i][j] = f[i - 1][j - 1] + 1 f[i][j]=f[i1][j1]+1

  2. 延长已有木板:如果选择延长已有木板,那么总长度将增加当前牛棚与前一个牛棚之间的距离,即 pp[i] - pp[i - 1]。这种情况下,状态转移方程为:
    f [ i ] [ j ] = f [ i − 1 ] [ j ] + ( p p [ i ] − p p [ i − 1 ] ) f[i][j] = f[i - 1][j] + (pp[i] - pp[i - 1]) f[i][j]=f[i1][j]+(pp[i]pp[i1])

最终,f[i][j] 的值为上述两种情况的较小值:
f [ i ] [ j ] = min ⁡ ( f [ i − 1 ] [ j − 1 ] + 1 , f [ i − 1 ] [ j ] + ( p p [ i ] − p p [ i − 1 ] ) ) f[i][j] = \min(f[i - 1][j - 1] + 1, f[i - 1][j] + (pp[i] - pp[i - 1])) f[i][j]=min(f[i1][j1]+1,f[i1][j]+(pp[i]pp[i1]))

初始化

在动态规划过程中,初始化是非常重要的一步。

  • 当没有任何牛棚和木板时,总长度为 0,即:
    f [ 0 ] [ 0 ] = 0 f[0][0] = 0 f[0][0]=0

  • 对于其他不可达的状态,我们将其初始化为一个很大的值(如 1 << 30),表示这些状态在初始阶段是不可到达的。

代码实现

以下是基于上述思路的完整代码实现:

#include<bits/stdc++.h>
using namespace std;int m, s, c; // 木板的最大数目、牛棚的总数和牛的数量
int f[205][205] = {0}; // 动态规划表
int pp[205] = {0}; // 牛棚编号数组int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> m >> s >> c; // 输入木板数、牛棚总数和牛的数量for (int i = 1; i <= c; ++i) {cin >> pp[i]; // 输入牛所在的牛棚编号}sort(pp + 1, pp + c + 1); // 对牛棚编号进行排序// 初始化DP表for (int i = 1; i <= c; ++i) f[i][0] = 1 << 30;for (int i = 1; i <= m; ++i) f[0][i] = 1 << 30;// 填充DP表for (int i = 1; i <= c; ++i) {for (int j = 1; j <= m; ++j) {f[i][j] = min(f[i - 1][j - 1] + 1, f[i - 1][j] + (pp[i] - pp[i - 1]));}}cout << f[c][m] << endl; // 输出结果return 0;
}

测试与验证

我使用题目中的样例输入对代码进行了测试:

输入:
4 50 18
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43

输出结果为 135,与题目中的预期结果一致。这表明代码能够正确处理样例输入,并计算出覆盖所有有牛的牛棚所需的最小木板总长度。

总结与拓展

通过动态规划的方法,我们可以高效地解决修理牛棚的问题。动态规划的核心在于将复杂问题分解为简单子问题,利用状态转移方程逐步构建解决方案。在这个过程中,我们不仅需要仔细设计状态表示,还需要合理推导状态转移方程,以确保算法的正确性和高效性。

这种方法不仅适用于这道题,还可以解决类似的区间覆盖问题。通过不断练习和总结,我们可以更好地掌握动态规划的思想和技巧,提升解决复杂问题的能力。希望这篇题解能够帮助你更好地理解动态规划的应用,以及如何在实际问题中灵活运用它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/84365.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙版Flutter库torch_light手电筒功能深度适配

鸿蒙版Flutter库torch_light手电筒功能深度适配&#xff1a;跨平台开发者的光明之路 本项目作者&#xff1a;kirk/坚果 适配仓库地址 作者仓库&#xff1a;https://github.com/svprdga/torch_light# 在数字化浪潮的推动下&#xff0c;跨平台开发框架如 Flutter 凭借其高效、…

【信息系统项目管理师】一文掌握高项常考题型-项目进度类计算

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 一、进度类计算的基本概念1.1 前导图法1.2 箭线图法1.3 时标网络图1.4 确定依赖关系1.5 提前量与滞后量1.6 关键路径法1.7 总浮动时间1.8 自由浮动时间1.9 关键链法1.10 资源优化技术1.11 进度压缩二、基本公式…

深入了解linux系统—— 操作系统的路径缓冲与链接机制

前言 在之前学习当中&#xff0c;我们了解了被打开的文件是如何管理的&#xff1b;磁盘&#xff0c;以及ext2文件系统是如何存储文件的。 那我们要打开一个文件&#xff0c;首先要先找到这个文件&#xff0c;操作系统又是如何去查找的呢&#xff1f; 理解操作系统搜索文件 …

Docker Hub仓库介绍

Docker Hub仓库全解析&#xff1a;从公共市场到私有化部署指南 一、Docker Hub公共镜像市场 1.1 核心功能解析 全球最大容器镜像库&#xff1a;累计托管超500万镜像核心服务矩阵&#xff1a; #mermaid-svg-CAMkhmtSWKEUw7z0 {font-family:"trebuchet ms",verdana,a…

redis使用RDB文件恢复数据

设置存盘间隔为120秒且10个key改变数据自动存盘使用RDB文件恢复数据 IP地址主机名192.168.10.170redis170 [rootredis170 ~]# yum install -y redis [rootredis170 ~]# systemctl start redis步骤一&#xff1a;设置存盘间隔为120秒且10个key改变自动存盘 [rootredis170 ~]#…

SpringBoot多环境配置文件切换

resources下application.yml、application-dev.yml、application-prod.yml多个配置文件。 spring:profiles:active: devspring:profiles:active: prod一般都是通过修改spring.profiles.active值来修改加载不同环境的配置信息&#xff0c;可以把切换的dev/prod放到pom.xml文件来…

Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用

Java 并发编程高级技巧&#xff1a;CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用 一、引言 在 Java 并发编程中&#xff0c;CyclicBarrier、CountDownLatch 和 Semaphore 是三个常用且强大的并发工具类。它们在多线程场景下能够帮助我们实现复杂的线程协调与资源控…

【Java多线程】多线程状态下如何安全使用ArrayList以及哈希表

&#x1f50d; 开发者资源导航 &#x1f50d;&#x1f3f7;️ 博客主页&#xff1a; 个人主页&#x1f4da; 专栏订阅&#xff1a; JavaEE全栈专栏 多线程安全使用ArrayList 手动加锁 日常中最常用的方法&#xff0c;使用synchronized进行加锁&#xff0c;把代码打包成一份&a…

InnoDB引擎底层解析(二)之InnoDB的Buffer Pool(三)

Buffer Pool 实例 我们上边说过&#xff0c;Buffer Pool 本质是 InnoDB 向操作系统申请的一块连续的内存空间&#xff0c;在多线程环境下&#xff0c;访问 Buffer Pool 中的各种链表都需要加锁处理&#xff0c;在Buffer Pool特别大而且多线程并发访问特别高的情况下&#xff0…

Netty学习专栏(三):Netty重要组件详解(Future、ByteBuf、Bootstrap)

文章目录 前言一、Future & Promise&#xff1a;异步编程的救星1.1 传统NIO的问题1.2 Netty的解决方案1.3 代码示例&#xff1a;链式异步操作 二、ByteBuf&#xff1a;重新定义数据缓冲区2.1 传统NIO ByteBuffer的缺陷2.2 Netty ByteBuf的解决方案2.3 代码示例&#xff1a;…

Vue3逐步抛弃虚拟Dom,React如何抉择

虚拟DOM&#xff1a;前端界的替死鬼 这玩意儿就是个前端开发的充气娃娃&#xff01; 你以为它很牛逼&#xff1f;无非是给真DOM当替死鬼&#xff01; 每次数据变&#xff0c;虚拟DOM先搁内存里自嗨一顿&#xff0c;diff算法跟便秘似的算半天&#xff0c;最后才敢碰真DOM。 说白…

分布式锁总结

文章目录 分布式锁什么是分布式锁&#xff1f;分布式锁的实现方式基于数据库(mysql)实现基于缓存(redis)多实例并发访问问题演示项目代码(使用redis)配置nginx.confjmeter压测复现问题并发是1&#xff0c;即不产生并发问题并发30测试,产生并发问题(虽然单实例是synchronized&am…

解决自签名证书HTTPS告警:强制使用SHA-256算法生成证书

解决自签名证书HTTPS告警&#xff1a;强制使用SHA-256算法生成证书 一、问题场景 在使用OpenSSL生成和配置自签名证书时&#xff0c;常遇到以下现象&#xff1a; 浏览器已正确导入根证书&#xff08;.pem文件&#xff09;&#xff0c;但访问HTTPS站点时仍提示不安全连接或证…

线上 Linux 环境 MySQL 磁盘 IO 高负载深度排查与性能优化实战

目录 一、线上告警 二、问题诊断 1. 系统层面排查 2. 数据库层面分析 三、参数调优 1. sync_binlog 参数优化 2. innodb_flush_log_at_trx_commit 参数调整 四、其他优化建议 1. 日志文件位置调整 2. 生产环境核心参数配置模板 3. 突发 IO 高负载应急响应方案 五、…

window 显示驱动开发-初始化和 DMA 缓冲区创建

若要指示 GPU 支持 GDI 硬件加速&#xff0c;显示微型端口驱动程序的 DriverEntry 函数实现必须使用指向驱动程序实现的 DxgkDdiRenderKm 函数的指针填充 DRIVER_INITIALIZATION_DATA 结构的 DxgkDdiRenderKm 成员。 DirectX 图形内核子系统调用 DxgkDdiRenderKm 函数&#xf…

Go语言实战:使用 excelize 实现多层复杂Excel表头导出教程

Go 实现支持多层复杂表头的 Excel 导出工具 目录 项目介绍依赖说明核心结构设计如何支持多层表头完整使用示例总结与扩展 项目介绍 在实际业务系统中&#xff0c;Excel 文件导出是一项常见功能&#xff0c;尤其是报表类需求中常见的复杂多级表头&#xff0c;常规表格组件往…

机器视觉6-halcon高级教程

机器视觉6-halcon高级教程 双目立体视觉原理视差外极线几何双目标定 双目立体视觉之Halcon标定一&#xff0e;标定结果二.Halcon标定过程1.获取左右相机图像中标定板的区域;2.提取左右相机图像中标定板的MARK点坐标和摄像机外部参数;3.执行双目标定;4.获取非标准外极线几何到标…

板凳-------Mysql cookbook学习 (六)

2025年Pytorch-gpu版本安装&#xff08;各种情况适用自己的安装需求&#xff0c;亲测绝对有效&#xff0c;示例安装torch2.6.0&#xff0c;过程详细面向小白&#xff09;_torch gpu版本-CSDN博客 https://blog.csdn.net/OpenSeek/article/details/145795127 2.2 查错 import s…

Spring boot和SSM项目对比

目录对比 springboot目录 project├─src│ ├─main│ │ ├─java│ │ │ ├─com.example.demo│ │ │ │ ├─config // 存放SpringBoot的配置类│ │ │ │ ├─controller // 存放控制器类│ │ │ │ ├─entity // 存…

《关于浔川社团退出DevPress社区及内容撤回的声明》

《关于浔川社团退出DevPress社区及内容撤回的声明》 尊敬的DevPress社区及读者&#xff1a; 经浔川社团内部决议&#xff0c;我社决定自**2025年5月26日**起正式退出DevPress社区&#xff0c;并撤回所有由我社成员在该平台发布的原创文章。相关事项声明如下&#xff1a; …