专栏文章

题解:UVA11413 Fill the Containers

UVA11413题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipxzzx0
此快照首次捕获于
2025/12/03 19:47
3 个月前
此快照最后确认于
2025/12/03 19:47
3 个月前
查看原文

题目传送门


题意

nn 瓶牛奶,我们要将这 nn 瓶牛奶倒入 mm 个容器当中,其中:
  1. 一个瓶子中的牛奶必须全部倒入容器之中。
  2. 先出现的容器先装牛奶。
  3. 靠在前面的容器只能被更靠前的容器装牛奶。
现在我们有 mm 个用来装牛奶的容器,试求这 mm 个容器中容量最大的容器的最小容量。

思路

看到“试求这 mm 个容器中容量最大容器的最小容量”,显而易见,这道题就是一道二分答案题。
我们用二分的左边界来解决,将序列分割成 mm 个子序列,二分答案的时候把选择的序列跟 mm 比较即可。

代码

CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;

int n, m, a[1001];

bool check(int x) {
    int temp = 1, sum = 0;
    for (int i = 1; i <= n; i++) {
        sum += a[i];
        if (sum > x) {
            temp++;
            sum = a[i];
        }
    }
    return temp <= m;
}

signed main() {
    while (cin >> n >> m) {
        int maxn = INT_MIN, sum = 0;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            sum += a[i];
            maxn = max(maxn, a[i]);
        }
        int left = maxn, right = sum;
        while (left < right) {
            int middle = (left + right) / 2;
            if (check(middle)) {
                right = middle;
            } else {
                left = middle + 1;
            }
        }
        cout << right << endl;
    }
    return 0;
}

代码说明

  1. 输入部分
    • 读取 nn mm ,表示牛奶瓶数和容器数。
    • 读取每瓶牛奶的容量 a[i]a[i] ,并计算总容量 sumsum 和最大容量 maxnmaxn
  2. 二分查找
    • 初始化二分查找的左右边界:left=maxnleft = maxn right=sumright = sum
    • 在每次二分中,计算中间值 middlemiddle ,并调用 check 函数检查是否可以将牛奶分配到 mm 个容器中。
    • 根据 check 函数的返回值调整左右边界。
  3. check 函数
    • 模拟将牛奶分配到容器中的过程。
    • 如果当前容器的容量超过 xx ,则开启一个新的容器。
    • 最终判断所需的容器数是否不超过 mm

复杂度分析

  • 时间复杂度O(nlog(sum))O(n \log(\text{sum})) ,其中 sum\text{sum} 是所有牛奶的总容量。
  • 空间复杂度O(n)O(n) ,用于存储每瓶牛奶的容量。

示例

输入:

CPP
5 3
4 2 4 5 1

输出:

CPP
6

总结

  • 本题通过二分查找和贪心策略,解决了将牛奶分配到容器中的问题。
  • 使用 check 函数验证二分答案的可行性,确保最大容量的最小化。

评论

0 条评论,欢迎与作者交流。

正在加载评论...