P1182 数列分段 Section II——二分
题目描述
对于给定的一个长度为
关于最大值最小:
例如一数列
将其如下分段:
第一段和为
将其如下分段:
第一段和为
并且无论如何分段,最大值不会小于
所以可以得到要将数列
输入格式
第
第
输出格式
一个正整数,即每段和最大值最小为多少。
输入输出样例 #1
输入 #1
5 3 4 2 4 5 1
输出 #1
6
说明/提示
对于
对于
对于
#include <iostream> #include <vector> #include <climits> using namespace std; int n, m; vector<int> a; // 检查在每段和的最大值为 mid 的情况下,能否将数列分成不超过 m 段 bool check(int mid) { int segments = 1; // 初始段数为 1 int current_sum = 0; // 当前段的和 for (int i = 0; i < n; i++) { if (current_sum + a[i] > mid) { // 如果加上当前元素后和超过 mid,开始新的一段 segments++; current_sum = a[i]; } else { // 否则,继续累加当前段的和 current_sum += a[i]; } } // 判断段数是否不超过 m return segments <= m; // ★★★ } int main() { cin >> n >> m; int a_max = 0; // 记录数列中的最大值 int a_sum = 0; // 记录数列的总和 for (int i = 0; i < n; i++) { int b; cin >> b; a.push_back(b); a_sum += b; a_max = max(a_max, b); } int left = a_max; // 左边界为数列中的最大值 int right = a_sum; // 右边界为数列的总和 int ans; // 二分查找每段和的最大值的最小值 while (left <= right) { int mid = left + (right - left) / 2; if (check(mid)) { ans = mid; right = mid - 1; // 尝试更小的最大值 } else { left = mid + 1; // 尝试更大的最大值 } } cout << ans << endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了