- 问题描述
Lazy有N个礼物需要打成M个包裹,邮寄给M个人,这些礼物虽然很便宜,但是很重。Lazy希望每个人得到的礼物的编号都是连续的。为了避免支付高昂的超重费,他还希望让包裹的最大重量最小。- 输入格式
一行两个整数N和M。 一行N个整数,表示N个礼物的重量。- 输出格式
一个整数,表示最大连续子序列的和- 数据规模和约定
N, M <= 100,000 重量 <= 1,000
大致思路:
打包可能的重量范围为单体最大到整体和之间。
在此范围内二分法。
用函数判断此情况是否可行。
思路借鉴:https://blog.csdn.net/qq_51439643/article/details/121364655?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164870863216780357228740%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164870863216780357228740&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-121364655.142v5pc_search_result_cache,143v6control&utm_term=%E6%89%93%E5%8C%85+%E8%93%9D%E6%A1%A5+C%2B%2B&spm=1018.2226.3001.4187
#include<iostream>
#include<algorithm>
using namespace std;
long long maxx = 0, sum = 0;
long long l,r,mid;
int n, m;
int x[100001];
bool trying(int* x, int mid)
{
int k=0,i;
int pack=0;
for (i= 0; i < n; i++)
{
if (x[i] > mid) return false;
k += x[i];
if (k > mid)
{
pack++;
k = x[i];
}
}
return pack < m;
}
int main()
{
int i;
cin >> n >> m;
for (i = 0; i < n; i++)
{
cin >> x[i];
sum += x[i];
if (maxx < x[i])
maxx = x[i];
}
// mid = (maxx + sum) / 2;
l = maxx;
r = sum;
while (l < r)
{
mid = (l + r) / 2;
if (trying(x, mid))
r = mid;
else
l = mid + 1;
}
cout << l;
return 0;
}