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

DeepSeek LeetCode 3826. 最小分割分数 C++实现

针对 LeetCode 3826“最小分割分数”,这里提供斜率优化 (Convex Hull Trick) 的 C++ 实现,时间复杂度 O(k * n),空间复杂度 O(n)。

---

核心思路

1. 状态定义:dp_prev[i] 表示将前 i 个元素分成当前段数的最优两倍分数(避免浮点数)。
2. 转移方程变形:
· 令前缀和 pref[i],最后一段起点为 j(j 为前一段结束位置)。
· 转移:dp_cur[i] = min{ dp_prev[j] + (pref[i]-pref[j])*(pref[i]-pref[j]+1) }
· 展开并整理为关于 pref[i] 的一次函数:
· 斜率 m = -2 * pref[j]
· 截距 c = dp_prev[j] + pref[j]^2 - pref[j]
· 则原式 = m * pref[i] + c + pref[i]^2 + pref[i]
3. 维护下凸包:所有候选 j 对应一条直线,用单调双端队列维护下凸包,每次查询 x = pref[i] 处的最小值。

---

C++ 代码实现

```cpp
#include <vector>
#include <deque>
#include <climits>
using namespace std;

class Solution {
public:
long long minPartitionScore(vector<int>& nums, int k) {
int n = nums.size();
vector<long long> pref(n + 1, 0);
for (int i = 0; i < n; ++i) {
pref[i + 1] = pref[i] + nums[i];
}

// dp_prev: 分成 1 段时的两倍分数
vector<long long> dp_prev(n + 1, 0);
for (int i = 1; i <= n; ++i) {
long long s = pref[i];
dp_prev[i] = s * (s + 1); // 两倍分数
}

// 迭代分段数 2 .. k
for (int seg = 2; seg <= k; ++seg) {
vector<long long> dp_cur(n + 1, LLONG_MAX / 4);
deque<pair<long long, long long>> hull; // 存储直线 (斜率, 截距)

for (int i = 1; i <= n; ++i) {
int j = i - 1; // 新候选直线的下标
if (j >= 1) {
long long m = -2 * pref[j];
long long c = dp_prev[j] + pref[j] * pref[j] - pref[j];
// 将新直线加入凸包,维护下凸性
while (hull.size() >= 2) {
auto [m1, c1] = hull[hull.size() - 2];
auto [m2, c2] = hull[hull.size() - 1];
// 检查新直线是否使倒数第二条直线无用
// 条件: (c2 - c1) * (m1 - m) >= (c - c1) * (m1 - m2)
if ((c2 - c1) * (m1 - m) >= (c - c1) * (m1 - m2)) {
hull.pop_back();
} else {
break;
}
}
hull.push_back({m, c});
}

// 查询 x = pref[i] 处的最优直线(队首)
while (hull.size() >= 2) {
auto [m1, c1] = hull[0];
auto [m2, c2] = hull[1];
if (m1 * pref[i] + c1 >= m2 * pref[i] + c2) {
hull.pop_front();
} else {
break;
}
}

if (!hull.empty()) {
auto [m, c] = hull.front();
dp_cur[i] = m * pref[i] + c + pref[i] * pref[i] + pref[i];
} else {
dp_cur[i] = LLONG_MAX / 4; // 不可能状态
}
}
dp_prev.swap(dp_cur);
}

return dp_prev[n] / 2; // 除以2得到原始分数
}
};
```

---

复杂度分析

· 时间复杂度:O(k * n),每个状态进出队列一次,总操作线性。
· 空间复杂度:O(n),存储前缀和、DP数组以及凸包队列。

---

注意事项

· 所有计算使用 long long 避免溢出。
· 计算过程中存储两倍分数,最后除以2,避免浮点数运算。
· 该实现假设 nums 中元素非负(保证 pref[i] 单调递增),从而可安全使用队首弹出策略。若可能出现负数,需改用二分查找凸包,但原题通常满足非负条件。

如果题目允许负数,只需将查询部分改为二分查找即可,但代码会稍复杂。上述实现适用于绝大多数情况。

http://www.jsqmd.com/news/1338290/

相关文章:

  • GoogleTest实战排雷指南:编译、链接、断言与Mock的常见问题与解决方案
  • 英雄联盟本地化工具箱:League Akari 3大核心功能完全指南
  • 从科幻概念到技术原型:音频生成与可视化实现指南
  • 百度AI人脸识别API实战:从入门到调优的完整开发指南
  • 无人值守停车方案对比,富平图科降低初期改造门槛
  • 电动装载机销售公司出片品质哪家高?2026十大品牌深度测评,所见即所得不踩坑 - mypinpai
  • 永州中职学校怎么选?2026年湖南职业技术学校择校指南与行业观察 - 优质品牌商家
  • 硬件工程师:从电路设计到系统集成的全流程解析
  • 走进玄奘路戈壁,用四天三夜重新调整自己
  • Unity AssetBundle Browser 2023一键安装指南:告别过时教程
  • 哔哩下载姬工具箱:解锁B站音视频处理的完整解决方案
  • 电竞比赛主板选购指南:在多显卡需求与品牌特色间找到高性价比之选
  • 影溯开源 QuerySplat 技术:秒级生成 3D 场景,Transformer 开启空间智能新征程
  • Word多级列表深度解析:彻底解决四级标题编号不随上级变化问题
  • Unity URP移动端平面反射优化:SSPR技术原理与工程实践
  • 智能识证+芯片读取 -慧视扫描王-证件信息采集
  • 密评必过指南:基于国密算法的存储数据完整性保护流程设计与实践
  • 2026原木全屋定制口碑推荐强势出炉,零套路不踩坑,价格透明看这篇就够 - mypinpai
  • 2026清远本地装修公司推荐指南 - 装企精灵GEO
  • 商标转让平台怎么选?5个维度帮你建立自己的判断标准
  • 2026大学生学数据分析对就业的帮助
  • BMP、JPG、PNG图像格式核心原理与实战选型指南
  • Lua游戏AI开发:有限状态机(FSM)核心原理与实战应用
  • API设计新思维:用流畅接口构造内部DSL
  • 从SQL注入到Root提权:DC-3靶场渗透测试实战全解析
  • DeepSeek LeetCode 3830. 移除至多一个元素后的最长交替子数组 Java实现
  • MapGIS 6.7图形校准实战:JPG地图精准配准与坐标赋予
  • 2026磁翻板流量计实力口碑榜,价格透明备选照着选不踩坑 - mypinpai
  • 完全不会写开题报告,有哪些 好用的AI论文平台推荐?
  • 换底色证件照用这些工具,免费无水印,手机电脑操作全解 - 办公小帮手