当前位置: 首页 > news >正文

UVa 366 Cutting Up

题目描述拼布者经常需要将布料切割成1×11 \times 11×1的小正方形。他们有一种特殊工具旋转切割刀可以一次切割多层布料切割层数的上限由布料类型决定题目输入的第一个参数KKK。切割时无论切割长度是多少难度都是一样的因此问题的关键是最小化切割次数而不是切割长度。切割规则如下布料可以叠放且叠放的布料不需要形状完全相同。切割之间可以重新排列布料。布料不能被折叠。切割必须沿整数坐标进行即从边到边将一块布料切成两块。最终必须得到m×nm \times nm×n个1×11 \times 11×1的小正方形没有浪费。输入包含多行每行三个整数KKK最大可切割层数1≤K≤2001 \le K \le 2001≤K≤200、mmm高度1≤m≤201 \le m \le 201≤m≤20、nnn宽度1≤n≤201 \le n \le 201≤n≤20。输入以0 0 0结束。输出格式为m by n takes x cuts每组输出后跟一个空行。题目分析这是一道具有特殊性质的最优化问题。直觉上切割布料的过程可以看作一开始有一块m×nm \times nm×n的矩形每次操作可以选择若干块布料数量不超过KKK将它们叠放在一起然后沿某条直线切一刀使得每块被切中的布料都分成两块更小的矩形。最终目标是全部变成1×11 \times 11×1。由于m,n≤20m, n \le 20m,n≤20状态空间理论上有限但直接BFS\texttt{BFS}BFS或DP\texttt{DP}DP会遇到两个困难状态表示复杂多重集最多400400400种不同的矩形每种数量可达400400400。每次切割可以同时处理多种不同形状的矩形分支因子极大。然而题目允许不同形状叠放这一特性大大简化了问题我们不再需要为每种形状单独考虑切割而是可以一次性切割当前所有“还需要被切”的矩形中最需要切的那些。解题思路贪心策略的合理性核心贪心策略是每一轮从所有尚未变成1×11 \times 11×1的矩形中选择面积最大的min⁡(K,需要切的矩形总数)\min(K, \text{需要切的矩形总数})min(K,需要切的矩形总数)个矩形每个矩形都沿着较长边的一半向下取整切一刀其余矩形保留不动。重复直到全部是1×11 \times 11×1。为什么这样能得到最优解一刀切多块由于允许不同形状叠放一次切割可以同时作用于多个矩形因此我们希望在每一刀中尽可能多地切割“大块”的矩形因为大块矩形需要更多次切割才能变小。按面积排序面积越大的矩形距离1×11 \times 11×1的“距离”越远优先处理它们可以更快地减少总工作量。沿较长边中间切这是最平衡的切法可以最大化切完后两块的“最小面积”从而让两块都能在后续被继续切割避免出现细长条需要额外切割的情况。实际上对于矩形每次切成两半或尽可能接近一半是最优的切割策略。与BFS\texttt{BFS}BFS或DP\texttt{DP}DP的关系理论上本题可以用BFS\texttt{BFS}BFS精确求解但状态空间巨大每种矩形的数量范围000到400400400有400400400种矩形BFS\texttt{BFS}BFS会组合爆炸。而本题的数据范围m,n≤20m,n \le 20m,n≤20和允许不同形状叠放使得贪心策略恰好是全局最优的。这种贪心可以被视为一种基于优先级的贪心BFS\texttt{BFS}BFS每一步都选择当前最紧迫的任务进行切割。DP\texttt{DP}DP方法也不可行因为切割过程涉及并行处理多个矩形无法简单地用单矩形的DP\texttt{DP}DP叠加。算法步骤用vectorpairint, int存储当前所有矩形的尺寸(width, height)初始只有一块(n, m)。初始化切割次数cuts 0。循环直到所有矩形都是1×11 \times 11×1收集所有面积大于111的矩形到needToCut。按面积降序排序。取前take min(K, needToCut.size())个矩形。对这些矩形若宽度 ≥ 高度则水平切将宽度分成width/2和width - width/2否则垂直切。未选中的矩形直接保留。切割次数加111。输出结果。复杂度分析每轮切割需要处理的矩形个数最多为当前布料的总块数。初始为111块之后每切一刀会增加若干块。由于每次切掉最大的矩形且切法平衡矩形数量增长较慢。总切割次数不超过m×nm \times nm×n最坏情况每次只切一块实际远小于此。空间复杂度O(m×n)O(m \times n)O(m×n)。代码实现// Cutting Up// UVa ID: 366// Verdict: Accepted// Submission Date: 2026-05-16// UVa Run Time: 0.010s//// 版权所有C2026邱秋。metaphysis # yeah dot net#includebits/stdc.husingnamespacestd;intmain(){intl,h,w;while(cinlhw){if(l0h0w0)break;// 当前所有矩形的集合每个矩形用 (width, height) 表示vectorpairint,intpieces;pieces.push_back({w,h});intcuts0;while(true){// 收集所有需要切割面积 1的矩形vectorpairint,intneedToCut;for(autop:pieces)if(p.first*p.second1)needToCut.push_back(p);if(needToCut.empty())break;// 全部是 1x1结束// 按面积降序排序优先切大块sort(needToCut.begin(),needToCut.end(),[](pairint,inta,pairint,intb){returna.first*a.secondb.first*b.second;});vectorpairint,intnewPieces;inttakemin(l,(int)needToCut.size());// 本次最多切 l 个// 对选中的矩形每个都从较长边的一半处切一刀for(inti0;itake;i){autopneedToCut[i];if(p.firstp.second){// 宽度 高度水平切newPieces.push_back({p.first/2,p.second});newPieces.push_back({p.first-(p.first/2),p.second});}else{// 高度 宽度垂直切newPieces.push_back({p.first,p.second/2});newPieces.push_back({p.first,p.second-(p.second/2)});}}// 未选中的矩形原样保留for(intitake;i(int)needToCut.size();i)newPieces.push_back(needToCut[i]);piecesnewPieces;cuts;}couth by w takes cuts cuts\n\n;}return0;}总结本题的关键在于认识到允许不同形状叠放使得我们可以在一刀中同时切割多个矩形从而将问题转化为一个贪心过程每次优先切割当前面积最大的若干个矩形且采用最平衡的切法。这种贪心策略在该问题的约束下能够达到全局最优代码实现简洁高效。
http://www.zskr.cn/news/1302664.html

相关文章:

  • KnowAgent:知识驱动的大模型智能体规划框架解析与实践
  • LinuxACL权限模型稳定性治理方法
  • 智慧课堂后端架构解析:微服务、实时通信与性能优化实战
  • AI编程助手插件:提升Minecraft Forge模组开发效率的实践指南
  • 从咒语到结构化指令:提示工程核心方法论与实践指南
  • Code Container:开箱即用的容器化开发环境实战指南
  • 容器化Emacs实践:Docker隔离环境实现开发配置可复现
  • 告别答辩PPT焦虑:百考通AI智能生成,高效搞定毕业答辩全流程
  • 【2026最新】鸿蒙NEXT培训班管理系统实战:从零搭建完整项目架构
  • ESP8266无线通信避坑实录:从‘找不到串口’到‘中文乱码’,我踩过的坑你都别踩
  • Python爬虫实战:小红书数据采集工具xhs-skill核心原理与应用
  • TransPrompt:大语言模型应用开发中的提示词转换与标准化实践
  • 百度网盘提取码3秒破解:智能查询工具的终极效率革命
  • 量子私有信息检索(QPIR)技术解析与应用前景
  • 生产环境紧急修复如何从 tag 创建 hotfix 分支流程?
  • Python创意编程入门:用DrawBot实现矢量图形与数据可视化
  • 手机号归属地查询系统:3步构建可视化定位工具
  • AI编程实战指南:从Prompt技巧到工程化集成
  • 嵌入式多核通信框架OpenPisci:轻量级IPC设计与RTOS解耦实践
  • 如何查看windows端口占用情况,禁止Win11系统自动更新工具
  • 多维子集和问题:NP难问题的算法与应用解析
  • 用ESP32+GRBL打造无线写字机器人:蓝牙/WIFI控制与离线绘图全攻略
  • 用51单片机和HC-SR04超声波模块DIY一个倒车雷达(附完整代码和立创EDA原理图)
  • 打造专业GitHub个人主页:从README驱动开发到自动化名片
  • 如何利用ArchivePasswordTestTool快速找回遗忘的压缩包密码:终极免费解决方案
  • Gopeed下载器深度解析:从零开始构建你的全平台高速下载解决方案
  • 为什么OpenBoardView成为硬件工程师必备的开源PCB查看器?
  • 如何快速掌握Fire Dynamics Simulator:火灾模拟专家的完整实战指南
  • 告别手动框选!用SUSTechPOINTS的V键批量标注,5分钟搞定一帧点云
  • 移动端AI编程助手:本地化GPT集成与开发效率革命