分割数组的最大值最小化(200分 / 二分答案 + 贪心)

题目描述 :给定一个非负整数数组 nums 和一个整数 m,将数组分成 m 个连续子数组,使得这 m 个子数组各自和的最大值最小。输出这个最小值。

输入:

  • 第一行:n m(1 ≤ n ≤ 10^5,1 ≤ m ≤ n)

  • 第二行:n 个非负整数

输出:最小的最大子数组和。

示例:

text

复制代码
输入:
5 2
7 2 5 10 8

输出:
18

解释:分成 [7,2,5] 和 [10,8],最大和为 18。

解题思路

二分答案:

  • 下界 lo = max(nums),上界 hi = sum(nums)。

  • 对于候选值 mid,贪心判断能否用不超过 m 个子数组使每个子数组和 ≤ mid。

  • 若能,说明答案可以更小,hi = mid;否则 lo = mid + 1。

参考代码

c

复制代码
#include <stdio.h>

int canSplit(int *nums, int n, int m, long long limit) {
    int cnt = 1;
    long long sum = 0;
    for (int i = 0; i < n; i++) {
        if (sum + nums[i] > limit) {
            cnt++;
            sum = nums[i];
            if (cnt > m) return 0;
        } else {
            sum += nums[i];
        }
    }
    return 1;
}

int main(void) {
    int n, m;
    scanf("%d %d", &n, &m);

    int nums[100005];
    long long lo = 0, hi = 0;
    for (int i = 0; i < n; i++) {
        scanf("%d", &nums[i]);
        if (nums[i] > lo) lo = nums[i];
        hi += nums[i];
    }

    while (lo < hi) {
        long long mid = lo + (hi - lo) / 2;
        if (canSplit(nums, n, m, mid))
            hi = mid;
        else
            lo = mid + 1;
    }

    printf("%lld\n", lo);
    return 0;
}
相关推荐
路灯上の马陈10 分钟前
二叉树的定义与性质
数据结构·二叉树·树结构·1024程序员节
小蒋观天下3 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
Bshaya_3 小时前
红黑树详解:概念、规则与插入实现
数据结构·红黑树·二叉搜索树·平衡树·插入逻辑
WBluuue4 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
路灯上の马陈5 小时前
数据结构-树
数据结构·1024程序员节
澳鹏Appen5 小时前
澳鹏重磅发布ExamOCRBench:面向端到端试卷判分的多任务基准
算法·benchmark·基准评测
benjormin5 小时前
Java数据结构 二叉搜索树
数据结构·算法
人工智能培训6 小时前
知识图谱:结构化表达实体与关系的知识组织技术
大数据·人工智能·算法·重构·生活·知识图谱
地平线开发者6 小时前
QAT 实战:从 PyTorch 模型到 J6E 实板精度与延时验证
pytorch·算法·自动驾驶