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

UVa 1336 Fixing the Great Wall

题目描述

长城上有 nnn 个损坏的区段需要修复,每个区段的位置为 pip_ipi,立即修复的成本为 cic_ici,每延迟一个时间单位修复,成本会增加 Δi\Delta_iΔiGWARR\texttt{GWARR}GWARR 机器人从初始位置 xxx 出发,以速度 vvv 在长城上移动。一旦机器人到达某个损坏区段的位置,可以瞬间完成修复。要求确定修复顺序,使得总成本最小。

输入格式

  • 多组测试数据,每组第一行是 n,v,xn, v, xn,v,x
  • 接下来 nnn 行,每行 pi,ci,Δip_i, c_i, \Delta_ipi,ci,Δi
  • 输入以 n=v=x=0n = v = x = 0n=v=x=0 结束

输出格式

  • 每组数据输出一个整数,表示最小成本(向下取整)

题目分析

问题性质

这是一个典型的区间动态规划问题,具有以下特点:

  1. 时间累积成本:每个区段的修复成本随时间线性增长
  2. 移动时间成本:机器人移动需要时间,影响所有未修复区段的成本
  3. 位置相关性:所有区段位于一条直线上,修复顺序影响移动路径

关键观察

  1. 最优子结构:在最优修复序列中,任意连续区间 [i,j][i,j][i,j] 的修复也是最优的
  2. 区间扩展:可以从单个点开始,向左右扩展修复区间
  3. 状态记录:需要记录当前修复区间和机器人的最后位置

动态规划设计

定义两个 DP\texttt{DP}DP 数组:

  • dpLeft[i][j]dpLeft[i][j]dpLeft[i][j]:修复区间 [i,j][i,j][i,j] 且机器人最后停在左端点 iii 时的最小成本
  • dpRight[i][j]dpRight[i][j]dpRight[i][j]:修复区间 [i,j][i,j][i,j] 且机器人最后停在右端点 jjj 时的最小成本

状态转移

  • dpLeft[i+1][j]dpLeft[i+1][j]dpLeft[i+1][j] 扩展到 dpLeft[i][j]dpLeft[i][j]dpLeft[i][j]:从 i+1i+1i+1 移动到 iii
  • dpRight[i+1][j]dpRight[i+1][j]dpRight[i+1][j] 扩展到 dpLeft[i][j]dpLeft[i][j]dpLeft[i][j]:从 jjj 移动到 iii
  • 右端点扩展同理

成本计算
移动时间 = 距离 / 速度
延迟成本 = 移动时间 × 所有未修复区段的 Δ\DeltaΔ 之和

算法步骤

  1. 将损坏区段按位置排序
  2. 添加虚拟起点(机器人初始位置)
  3. 计算 Δ\DeltaΔ 的前缀和,用于快速计算未修复区段的 Δ\DeltaΔ
  4. 初始化 DP\texttt{DP}DP 数组
  5. 按区间长度从小到大进行 DP\texttt{DP}DP
  6. 输出最终结果

复杂度分析

  • 时间复杂度O(n2)O(n^2)O(n2),需要填充 n×nn \times nn×nDP\texttt{DP}DP
  • 空间复杂度O(n2)O(n^2)O(n2),存储两个 DP\texttt{DP}DP 数组

代码实现

// Fixing the Great Wall
// UVa ID: 1336
// Verdict: Accepted
// Submission Date: 2025-10-24
// UVa Run Time: 0.100s
//
// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include <bits/stdc++.h>
using namespace std;const int MAX_N = 1005;
const double INF = 1e18;struct Section {int position;int baseCost;int deltaCost;bool operator<(const Section& other) const {return position < other.position;}
} sections[MAX_N];int numSections, robotSpeed, startPosition;
double dpLeft[MAX_N][MAX_N], dpRight[MAX_N][MAX_N];
int prefixSumDelta[MAX_N];// 获取区间 [l, r] 之外的 delta 成本之和
int getRemainingDeltaSum(int left, int right) {return prefixSumDelta[numSections] - (prefixSumDelta[right] - prefixSumDelta[left - 1]);
}int main() {ios::sync_with_stdio(false);cin.tie(0);while (cin >> numSections >> robotSpeed >> startPosition) {if (numSections == 0 && robotSpeed == 0 && startPosition == 0) break;// 读取损坏区段数据for (int i = 1; i <= numSections; i++) {cin >> sections[i].position >> sections[i].baseCost >> sections[i].deltaCost;}// 添加虚拟起点(机器人初始位置)numSections++;sections[numSections].position = startPosition;sections[numSections].baseCost = 0;sections[numSections].deltaCost = 0;// 按位置排序sort(sections + 1, sections + numSections + 1);// 计算 delta 成本的前缀和prefixSumDelta[0] = 0;for (int i = 1; i <= numSections; i++) {prefixSumDelta[i] = prefixSumDelta[i - 1] + sections[i].deltaCost;}// 找到机器人初始位置对应的索引int startIndex = -1;for (int i = 1; i <= numSections; i++) {if (sections[i].position == startPosition && sections[i].baseCost == 0 && sections[i].deltaCost == 0) {startIndex = i;break;}}// 初始化 DP 数组for (int i = 1; i <= numSections; i++) {for (int j = i; j <= numSections; j++) {dpLeft[i][j] = dpRight[i][j] = INF;}}dpLeft[startIndex][startIndex] = dpRight[startIndex][startIndex] = 0;// 区间动态规划for (int length = 2; length <= numSections; length++) {for (int i = 1; i + length - 1 <= numSections; i++) {int j = i + length - 1;// 从左边扩展:最后停在左端点 idouble costFromLeft = dpLeft[i + 1][j] + (sections[i + 1].position - sections[i].position) * 1.0 / robotSpeed * getRemainingDeltaSum(i + 1, j);double costFromRight = dpRight[i + 1][j] + (sections[j].position - sections[i].position) * 1.0 / robotSpeed * getRemainingDeltaSum(i + 1, j);dpLeft[i][j] = min(costFromLeft, costFromRight) + sections[i].baseCost;// 从右边扩展:最后停在右端点 jcostFromRight = dpRight[i][j - 1] + (sections[j].position - sections[j - 1].position) * 1.0 / robotSpeed * getRemainingDeltaSum(i, j - 1);costFromLeft = dpLeft[i][j - 1] + (sections[j].position - sections[i].position) * 1.0 / robotSpeed * getRemainingDeltaSum(i, j - 1);dpRight[i][j] = min(costFromRight, costFromLeft) + sections[j].baseCost;}}// 输出结果(向下取整)long long result = (long long)floor(min(dpLeft[1][numSections], dpRight[1][numSections]));cout << result << "\n";// 恢复 numSections 的原始值numSections--;}return 0;
}

总结

本题通过区间动态规划巧妙地解决了带时间累积成本的路径规划问题。关键点在于:

  1. 将机器人初始位置作为虚拟起点
  2. 使用两个 DP\texttt{DP}DP 数组分别记录停在区间两端的状态
  3. 利用前缀和快速计算未修复区段的延迟成本

这种解法在 n≤1000n \leq 1000n1000 的规模下具有很好的可行性,能够高效求出最小修复成本。

http://www.dtcms.com/a/525336.html

相关文章:

  • 网站开发浏览器关键词优化提升排名
  • 湖北省荆门市城乡建设网站seo代码优化有哪些方法
  • [Python快速入门]基础语法以及使用
  • el-table选中行颜色
  • Flask入门教程——李辉 第5章: 数据库 关键知识梳理
  • 嘉峪关市建设局建管科资质网站网站制作教程
  • 如何免费建设网站列表页面设计模板
  • 通过diskpart强制格式化报错:虚拟磁盘服务错误:卷大小太大
  • 02)PB(PowerBuilder9)学习 连接数据库 开发一个增删改查功能
  • Java 开发 - 扁平化数据转换成树形结构数据(递归查找 + 移除节点、Map + 一次遍历)
  • 探寻企业数字化转型“底座”:技术基石与核心支撑
  • 做网站视频教学最简单的出入库管理软件
  • [MySQL]表——改变数据
  • 第十一篇《IPv4的救星:初识IPv6的地址格式与优势》
  • 好的网站推荐住房和城乡建设部网站施工员证
  • C++开发之责任链模式
  • JVM面试(内存结构,垃圾回收,类载机制)
  • 并发编程案例分析——高性能限流器Guava RateLimiter(四十六)
  • 灵巧手——faive_gym
  • 亚马逊电子配件类目流量瓶颈突破:DeepBI智能优化策略助力流量增长
  • 桂市做网站的朋友自建电商网站有哪些
  • autoware源码编译
  • react nextjs 项目部署
  • 怎样建设网站 需要哪些条件免费的免抠图素材网站
  • FPGA学习笔记——用Vitis IDE生成工程(串口发送)
  • 烟台 o2o平台带动做网站行业平潭综合实验区交通与建设网站
  • GaussianShader
  • 昆山企业做网站好用的网站系统
  • javaScript事件委托
  • 广州营销型网站建设哪家好公司域名怎么起