资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
Lazy有N个礼物需要打成M个包裹,邮寄给M个人,这些礼物虽然很便宜,但是很重。Lazy希望每个人得到的礼物的编号都是连续的。为了避免支付高昂的超重费,他还希望让包裹的最大重量最小。
输入格式
一行两个整数N和M。
一行N个整数,表示N个礼物的重量。输出格式
一个整数,表示最小的最大重量。
样例输入
3 2
1 1 2样例输出
2
数据规模和约定
N, M <= 100,000
重量 <= 1,000
思路:
假设Max为众多礼物中最重的,r为所有礼物重量的总和,显然,所求答案就在区间[Max,r]间,采用二分的方法查询所求答案
#include<iostream>
using namespace std;
int n, m;
int weight[100050],Max=0;
int f(int mid) {
int sum = 0,p=1;//被打包在一起的礼物的总重,已经把n个包裹打包成p个包裹
for (int i = 0; i < n; i++) {
sum += weight[i];
if (p > m)//已经打包数比要发出去的包裹数大,该情况不合理
return 0;
if (sum > mid) {//算上第i个礼物,总重大于mid,则将前i-1个打包成一个,从第i个重新开始打包
sum = 0;
i--;
p++;
}
if (sum == mid) {
sum = 0, p++;
}
}
return 1;
}
int main() {
int r = 0;
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> weight[i];
if (weight[i] > Max)
Max = weight[i];
r += weight[i];
}
int l = Max;
while (r > l) {
int mid = (l + r) / 2;
if (f(mid))
r = mid;//没返回0,说明被打包数<=m,mid应该小一点,让打包数多一些
else
l = mid + 1;//一定要加一,否则因为整型除法的原因,会陷入死循环
}
cout << l;
return 0;
}