就是个贪心题,阅读理解把我卡死了orz(把题意读成可以把汉堡排分成两份同时做)
算出每个锅煎的最长时间:max(煎全部用的时间-1/锅的数量 +1,煎一个汉堡排用的最长时间)
这样能保证当一个汉堡排在当前锅时间不够用,放在下一个煎锅时,不会与上一个煎锅安排的时间出现重叠
然后就是贪心往锅里填就行了
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct node {
int id;//每个计划的编号
long long l, r; //不开long long 见祖宗
};
vector<node>g[N];//储存计划
int main() {
int n, m;
cin >> n >> m; //n个汉堡排,m个锅
long long sum = 0;
priority_queue<pair<int, int>>pq; //优先队列,优先序越大的在前面
for (int i = 1; i <= n; i++) { //每个汉堡排的要的时间
int t;
cin >> t;
pq.push({t, i}); //让花费时间长的在堆顶,先做时间长的
sum += t; //记录想要做完的总时间
}
long long ans = max((sum - 1) / m + 1, (long long)pq.top().first); //每个锅的最长煎的时间
//取平均时间或一个汉堡排最长时间的最大值,这样才能保证做一个汉堡排时用时不会重叠
//输出方式:K id L R K:做某个汉堡要用多少个锅 在L到R期间在id锅做汉堡排
//第i行表示做第i个汉堡排
int id = 1;
long long time = 0;
while (!pq.empty()) {
int t = pq.top().first; //用时
int i = pq.top().second; //编号
pq.pop();
if (time + t <= ans) { //当前时间里可以煎好
g[i].push_back({id, time, time + t});
time+=t;
} else { //当前时间煎不好,分成两段来煎
g[i].push_back({id, time, ans});
t -= ans - time; //还需要煮的时间
id++;
time = t;
g[i].push_back({id, 0, time});
}
if (time == ans) {
time = 0;
id++;
}
}
for (int i = 1; i <= n; i++) {
if (g[i].size() == 1) { //一个锅就做好了
printf("1 %d %lld %lld\n",
g[i][0].id, g[i][0].l, g[i][0].r);
} else {
printf("2 %d %lld %lld %d %lld %lld\n",
g[i][1].id, g[i][1].l, g[i][1].r,
g[i][0].id, g[i][0].l, g[i][0].r);
}
}
return 0;
}