F Hamburger Steak
题意
有 n n n 块牛排,编号为 1 ∼ n 1\sim n 1∼n,编号为 i i i 的牛排需要煎满 t i m i n t_imin timin,并且每块牛排最多只能被两个锅煎,一共有 m m m 个锅,问煎玩牛排需要的最短时间
考虑计算最小的锅使用时间的最大值,然后依次暴力去凑即可。
#include <bits/stdc++.h>
using namespace std;
#define int ll
#define rep(i, j, k) for (int i = j; i <= k; ++i)
#define rrep(i, j, k) for (int i = j; i >= k; i--)
typedef long long ll;
const int N = 1e5 + 7;
struct ans {
int k, l, r;
void print() { cout << k << ' ' << l << ' ' << r << ' '; }
};
struct steak {
int t, p;
vector<ans> res;
void print() {
rrep(i, res.size() - 1, 0) res[i].print();
cout << '\n';
}
} a[N];
signed main() {
int n, m, mx = 0, sum = 0;
cin >> n >> m;
rep(i, 1, n) cin >> a[i].t, a[i].p = i, sum += a[i].t, mx = max(mx, a[i].t);
mx = max(mx, sum / m + (sum % m != 0));
int last = 0, p = 1;
rep(i, 1, m) {
// last 表示当前距离凑到最大值还剩下多少,time 表示什么时候开始煎的
int last = mx - a[p].t, time = a[p].t;
a[p].res.push_back({i, 0, a[p].t});
p++;
while (last > 0 and p <= n)
if (a[p].t > last) {
a[p].res.push_back({i, time, mx});
a[p].t -= last;
last = 0;
} else {
last -= a[p].t;
a[p].res.push_back({i, time, time + a[p].t});
time += a[p++].t;
}
if (p > n)
break;
}
rep(i, 1, n) cout << a[i].res.size() << ' ', a[i].print();
return 0;
}