1 条题解
-
0
题目理解
给定 块原木板(长度为 )和 块需要的木板(长度为 ),通过切割原木板(不产生浪费)得到需要的木板。每块木板(原木板和需要的木板)只能使用一次。求最多能得到多少块需要的木板。
数据范围:
关键观察
1. 问题本质
这是一个典型的二分答案 + 可行性验证问题:
- 答案具有单调性:如果能得到 块需要的木板,那么一定能得到少于 块的
- 验证给定 是否可行:能否从原木板中切割出 块需要的木板
2. 贪心策略
- 优先切割较短的需要木板(容易满足)
- 优先使用较短的原木板(避免浪费)
- 如果当前需要的木板长度与原木板剩余长度相等,直接使用(不产生浪费)
算法设计
1. 预处理
- 将需要的木板长度 从小到大排序
- 将原木板长度 从小到大排序
- 计算原木板总长度 和需要木板的前缀和
2. 二分答案框架
二分答案 k (0 ≤ k ≤ n): - 如果 k=0: 一定可行 - 如果 pre_k > S_a: 不可能(总长度不足) - 否则进行 DFS 验证3. DFS 验证(可行性检查)
状态:
now: 当前要切割的第now块需要木板(前 k 块中)last: 上次使用的原木板编号(剪枝优化)waste: 已浪费的总长度(长度过小而无法利用的剩余部分)
剪枝优化:
- 长度剪枝:如果当前需要木板长度大于所有原木板剩余长度,则失败
- 浪费剪枝:如果
waste > S_a - pre_k,则失败- 浪费过多,剩余部分即使全部利用也无法完成
- 顺序剪枝:
- 如果当前需要木板长度 = 上一块长度,则从上一块使用的原木板开始尝试
- 避免重复搜索相同长度的木板
- 相等优先:优先使用与原木板剩余长度相等的需要木板(零浪费)
- 跳过无效:如果原木板剩余长度 < 当前需要木板长度,则跳过
4. 算法流程
1. 排序输入数据 2. 二分答案 k: a. 如果 k=0,返回 true b. 如果总长度不足,返回 false c. 初始化原木板剩余长度 d. 进行 DFS 验证 3. 输出最大可行的 k
算法正确性
1. 二分答案的正确性
- 单调性:如果能得到 块木板,那么通过减少切割,一定能得到 块
- 可行性验证:DFS 搜索所有可能的切割方案,确保不遗漏
2. 剪枝的合理性
- 浪费剪枝:基于总长度守恒,已浪费长度不能超过允许的最大浪费
- 顺序剪枝:相同长度的需要木板具有对称性,固定尝试顺序避免重复
- 相等优先:零浪费的切割是最优选择,优先尝试
3. 搜索完备性
DFS 遍历所有原木板和所有切割方式,在剪枝优化下仍保证能找到可行解(如果存在)
复杂度分析
时间复杂度
- 排序:
- 二分答案: 次迭代
- 每次验证:DFS 搜索,最坏情况 ,但通过剪枝大幅优化
- 实际运行效率: 下可接受
空间复杂度
- 存储原木板和需要木板:
- DFS 递归栈:
代码实现要点
1. 数据结构
int a[55]; // 原木板长度 int b[1005]; // 需要木板长度 int sum[1005]; // 需要木板前缀和 int rest[55]; // 原木板剩余长度 int n, m, total; // 需要木板数、原木板数、原木板总长度2. 关键函数
bool check(int k): 验证能否得到 k 块需要木板bool dfs(int now, int last, int waste): DFS 搜索可行性- 二分查找:寻找最大可行的 k
3. 优化技巧
- 预处理排序和前缀和
- DFS 中的多重剪枝
- 记录上次使用的原木板编号
- 优先处理相等情况(零浪费)
示例分析
样例 1
原木板: 25, 30, 40, 50 需要木板: 15, 16, 17, 18, 19, 20, 21, 24, 25, 30 答案: 7- 可以切割出:15, 16, 17, 18, 19, 20, 21(共7块)
- 使用原木板合理分配,避免浪费
样例 2
原木板: 10, 10, 20 需要木板: 3, 3, 3, 5, 5, 7, 8, 8, 9 答案: 7- 可以切割出:3, 3, 3, 5, 5, 7, 8(共7块)
- 充分利用每块原木板,最小化浪费
算法标签
- 二分
- 深度优先搜索(DFS)
- 剪枝优化
- 贪心策略
- 模拟
总结
本题通过二分答案将最优化问题转化为判定问题,再通过DFS+剪枝验证可行性。关键在于设计有效的剪枝策略:
- 浪费剪枝:基于总长度守恒
- 顺序剪枝:避免重复搜索相同状态
- 相等优先:零浪费切割最优
这些优化使得在 的数据范围内,算法能够在时限内运行。此题综合考察了二分答案、搜索剪枝和问题建模能力。
- 1
信息
- ID
- 5980
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者