示例1
输入
复制
5 3
1 2 3 4 5
输出
复制
1 1 0 1
1 2 0 2
1 2 2 5
1 1 1 5
1 3 0 5
说明
Other valid outputs, such as the one below, are also acceptable for the example input:
1 1 0 1
1 1 1 3
2 2 0 1 1 3 5
1 2 1 5
1 3 0 5
题意 :
- 有n个汉堡和m个锅,给出每个汉堡需要煎的时间ti。一个汉堡可以在一个锅中煎好,也可以分成两次在两个锅中煎好。一个锅同时只能煎一个汉堡,一个汉堡同时只能放到一个锅中,求一个方案使煎好所有汉堡所需要的时间最少。
思路 :
- 假设我们知道了最小耗时T,就可以贪心地将每个锅的时间T依次分配给每个汉堡,当前这个锅没煎完的部分再由下个锅煎即可。为了满足题目要求,我们要保证所有锅的时间和大于等于所有汉堡的时间和,以及耗时最长的汉堡不会在同一时刻被分在两个锅中(耗时小于它的自然也就满足条件),于是最小耗时T = max{max{ti}, sum(ti) / m}。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL a[N];
int main()
{
// ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n, m;
cin >> n >> m;
LL sum = 0, mx = 0;
for (int i = 0; i < n; i ++ ) cin >> a[i], sum += a[i], mx = max(mx, a[i]);
LL t = max(mx, sum / m + (sum % m != 0)); // 向上取整
LL nowt = 0, cnt = 1; // 当前使用第cnt个锅子,当前这个锅子处于的时间
for (int i = 0; i < n; i ++ )
{
if (nowt == t) cnt ++ , nowt = 0;
if (nowt + a[i] > t)
{
printf("2 %lld %lld %lld %lld %lld %lld\n", cnt + 1, 0, a[i] - (t - nowt), cnt, nowt, t);
cnt ++ , nowt = a[i] - (t - nowt);
}
else
{
printf("1 %lld %lld %lld\n", cnt, nowt, nowt + a[i]);
nowt += a[i];
}
}
return 0;
}