news 2026/4/18 8:22:45

瑞瑞的木板(洛谷P1334 )

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
瑞瑞的木板(洛谷P1334 )

题目背景

瑞瑞想要亲自修复在他的一个小牧场周围的围栏。

题目描述

他测量栅栏并发现他需要 n 根木板,每根的长度为整数 li​。于是,他买了一根足够长的木板,长度为所需的 n 根木板的长度的总和,他决定将这根木板切成所需的 n 根木板(瑞瑞在切割木板时不会产生木屑,不需考虑切割时损耗的长度)。

瑞瑞切割木板时使用的是一种特殊的方式,这种方式在将一根长度为 x 的木板切为两根时,需要消耗 x 个单位的能量。瑞瑞拥有无尽的能量,但现在提倡节约能量,所以作为榜样,他决定尽可能节约能量。显然,总共需要切割 (n−1) 次,问题是,每次应该怎么切呢?请编程计算最少需要消耗的能量总和。

输入格式

输入的第一行是整数,表示所需木板的数量 n。

第 2 到第 (n+1) 行,每行一个整数,第 (i+1) 行的整数 li​ 代表第 i 根木板的长度 li​。

输出格式

一个整数,表示最少需要消耗的能量总和。

输入输出样例

输入 #1复制运行

3 8 5 8

输出 #1复制运行

34

说明/提示

输入输出样例 1 解释

将长度为 21 的木板,第一次切割为长度为 8 和长度为 13 的,消耗 21 个单位的能量,第二次将长度为 13 的木板切割为长度为 5 和 8 的,消耗 13 个单位的能量,共消耗 34 个单位的能量,是消耗能量最小的方案。


数据规模与约定
  • 对于 100% 的数据,保证 1≤n≤2×104,1≤li​≤5×104。

1. 题目简介

本题是一个经典的“合并果子”或“哈夫曼编码”类型的变种问题。

题目要求将一根长木板切割成若干块给定长度的小木板,每次切割的代价是当前木板的长度。我们需要求出完成所有切割所需的最小总代价。

逆向思维:切割过程极其复杂,我们可以将其逆向思考为“合并”过程——将N块小木板每次两两合并,最终还原成一根长木板。每次合并的代价就是两块木板长度之和。问题转化为:如何通过合并策略,使得总消耗能量最小。

2. 解题思路

核心策略:贪心

为了让总代价最小,我们需要让长度长(权重很大)的木板尽可能少参与合并运算,而长度短的木板可以多次参与运算。

因此,我们的贪心策略是:每次都从当前所有木板中,取出长度最小的两块进行合并。

数据结构选择

由于每次合并后会产生一个新的木板长度,这个新长度需要放回集合中,并且可能会改变集合的大小顺序。

  • 如果使用数组排序:每次合并后都要重新排序,时间复杂度会达到O(N^2),容易超时。

  • 最佳选择:使用优先队列 (最小堆)

    • priority_queue可以以 O(log N) 的复杂度自动维护数据的有序性。

    • 取最小值、插入新值都非常高效。

算法流程

  1. 特判:如果只有 1 块木板,不需要切割,输出 0。

  2. 初始化:建立一个greater类型的优先队列(小根堆),将所有初始木板长度入队。

  3. 循环合并:当队列中元素大于 1 个时:

    • 取出堆顶(最小)元素a,弹出。

    • 再次取出堆顶(次小)元素b,弹出。

    • 计算代价sum+=a+b

    • 将合并后的新长度a+b重新推入堆中。

  4. 输出:最终的sum即为答案。

3. 核心总结

  • 算法本质:这就是经典的哈夫曼树构造过程。通过贪心策略,保证权值越小的节点离根越远(参与运算次数越多),权值越大的节点离根越近,从而使带权路径长度(WPL)最小。

  • 复杂度分析

    • 时间复杂度:每一轮合并涉及两次pop和一次push,操作次数为N-1次,堆操作复杂度为 O(log N),总时间复杂度为O(N log N)

    • 空间复杂度:需要存储N个元素,为O(N)

  • 避坑指南

    1. 数据类型:累加的代价sum可能会超过int范围,必须使用long long

    2. 边界条件:注意N=1的情况,此时不需要消耗能量。

    3. 堆的定义:STL 默认是大根堆,记得加上vector<long long>, greater<long long>定义为小根堆。


解题总结

遇到“合并代价最小”类问题,直接用小根堆,每次取俩最小、合二为一、扔回堆里,直到只剩一个,记得观察数据范围开long long。

//分割本质倒过来就是合并,这道题本质上是一道哈夫曼树,要让大数参与合并的次数尽可能少 #include <iostream> #include <queue> using namespace std; priority_queue<long long,vector<long long>,greater<long long>> q;//最小堆 int main(){ ios::sync_with_stdio(false); cin.tie(0); int n; cin>>n; if(n==1){//如果只有一根木板 不需要切 cout<<0; return 0; } long long sum=0;//消耗的总能量 for(int i=1;i<=n;i++){//把所有要切出来的木板长度入队 int tmp; cin>>tmp; q.push(tmp); } while(q.size()!=1){//当已经所有木板合并成一根木板就不要合并了 long long a=q.top();//每次合并里面最小的两根木板,这样越大木板参与合并的次数就会越少,那总能量消耗就会小 q.pop(); long long b=q.top(); q.pop(); q.push(a+b); sum=sum+a+b; } cout<<sum; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 19:29:09

Dify镜像安全性评估:企业生产环境是否值得信赖?

Dify镜像安全性评估&#xff1a;企业生产环境是否值得信赖&#xff1f; 在当前大模型技术席卷各行各业的背景下&#xff0c;越来越多的企业开始尝试将LLM能力集成到核心业务系统中——从智能客服、知识问答&#xff0c;到自动化内容生成与数据分析助手。然而&#xff0c;现实中…

作者头像 李华
网站建设 2026/4/7 20:28:35

基于Dify的AI应用快速原型设计方法论

基于Dify的AI应用快速原型设计方法论 在大模型技术席卷各行各业的今天&#xff0c;企业对AI功能的需求早已从“有没有”转向“快不快”。一个产品能否在两周内上线智能客服、自动生成报告或个性化推荐能力&#xff0c;往往直接决定了其市场竞争力。然而现实是&#xff0c;大多数…

作者头像 李华
网站建设 2026/4/18 5:33:55

11、软件设计模型的领域驱动复用:RSL语言助力软件开发

软件设计模型的领域驱动复用:RSL语言助力软件开发 1. 引言 在当今的软件开发领域,模型驱动开发(MDD)和软件复用是两个重要的基石。然而,将它们有效结合的实践却相对较少。有一种创新的方法,通过引入一种半形式化的需求规范语言(RSL),实现了这两者的自然融合,同时还为…

作者头像 李华
网站建设 2026/4/18 6:24:20

13、基于MDA的电子服务设计方法:从业务价值模型到系统实现

基于MDA的电子服务设计方法:从业务价值模型到系统实现 1. 引言 随着互联网的出现,企业向客户、供应商、商业伙伴和金融机构开放了其核心功能。万维网的迅猛发展为各类企业提供了将其价值主张以软件服务(即电子服务,e - services)的形式提供给消费者的机会,例如网上书店…

作者头像 李华
网站建设 2026/4/18 6:25:50

Dify如何帮助初创公司快速上线AI产品?

Dify如何帮助初创公司快速上线AI产品&#xff1f; 在当今的创业环境中&#xff0c;一个想法从灵感到落地的时间窗口正在急剧缩短。尤其是当整个行业都在追逐“AI”的机会时&#xff0c;能否在几周甚至几天内推出一款具备智能对话、知识问答或内容生成能力的产品&#xff0c;往往…

作者头像 李华
网站建设 2026/4/8 8:33:04

19、《图像传感器相关模式、缩放、压缩及数据传输详解》

《图像传感器相关模式、缩放、压缩及数据传输详解》 1. 100% Color Tile Mode 图像传感器应支持 100% Color Tile Mode,预计该模式在未来版本的 CCS 规范中将成为强制要求。在此模式下,所有像素数据会被替换为 8 条彩色瓷砖图案的拜耳版本。该图案由 N 行 100% 彩色条纹图案…

作者头像 李华