1 条题解
-
0
题解
问题分析
勇者需要按环形顺序击败所有怪物,每个怪物 有:
- 要求力量 (必须 ≥ 此值才能击败)
- 击败后增加力量
目标是找到最小的初始力量 ,使得存在一个起点 ,按环形顺序击败所有怪物。
关键观察
-
问题转化:环形序列可以拆成两段线性序列:
- 从 到 :怪物
- 从 到 :怪物
-
前缀和与后缀和:
- (前缀和)
- (后缀和)
-
约束条件:
- 对于位置 ,要求:
- 这可以转化为:
算法思路
预处理 + 枚举起点:
预处理数组
-
:处理前 个怪物时的最大约束
表示处理到第 个怪物时,初始力量需要满足的约束。
-
:处理后 个怪物时的最大约束(从右往左)
表示从位置 开始往右打到最后时,在位置 需要的力量。
计算答案
对于每个可能的起点 :
- 先打 ,需要力量
- 再打 ,此时已有力量 ,需要满足 的约束
- 所以初始力量需要:
取所有起点中的最小值。
核心代码逻辑
// 预处理后缀和 for (int i = n; i >= 1; --i) { s[i] = s[i + 1] + b[i]; } // 预处理前缀和 for (int i = 1; i <= n; ++i) { S[i] = S[i - 1] + b[i]; } // 从左往右处理约束 for (int i = 1; i <= n; ++i) { L[i] = max(L[i - 1], a[i] - S[i - 1]); } // 从右往左处理约束 for (int i = n; i >= 1; --i) { R[i] = max(R[i + 1] - b[i], a[i]); } // 枚举起点找最小值 ll ans = 1e18; for (int i = 1; i <= n; ++i) { ll res = max(R[i], L[i - 1] - s[i]); ans = min(ans, res); }复杂度分析
- 预处理: 计算前缀和、后缀和、 数组、 数组
- 枚举起点:
- 总复杂度:
算法步骤
- 读入
- 计算前缀和 和后缀和
- 从左到右计算 数组
- 从右到左计算 数组
- 枚举所有起点,计算所需初始力量
- 输出最小值
算法标签
- 前缀和/后缀和
- 动态规划
- 环形数组处理
- 贪心思想
- 最优化问题
- 1
信息
- ID
- 3968
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者