烙饼

烙饼问题(可抢占并行机调度)思路整理

整数规划特例

一、题目简述

有 n 个饼,需要烙制时间分别为 a[1..n];有 m 台完全相同的烙饼机,每台同时只能烙一个饼,且一个饼可被中断(即在某台机器上烙一会儿后取出,以后在任意机器上继续烙),每次烙制时间必须是整数分钟。要求制定一份烙制记录,使得所有饼的最晚完成时间(makespan)最小,并且记录条数 k 满足 1 ≤ k ≤ 2n。输出任意最优方案。


二、核心思路

1. 理论最优时间下界

设总烙制时间 S = sum(a),单个饼所需的最大时间为 mx = max(a)。

  • 因为共有 m 台机器,总工作量 S 必须由它们分担,因此任何方案的最晚完成时间 T 至少为 ceil(S / m)。
  • 又因为同一个饼不能被同时烙,所以任何方案的最晚完成时间至少为 mx。

所以最优时间 T 的下界为:

T = max( mx, ceil(S / m) )

这个下界是可达的(因为允许抢占),因此它就是真正的最优解。


三、构造最优方案(McNaughton 算法)

1. 将总工作量拉成一根时间轴

想象将所有饼按顺序首尾相连排成一根长度为 S 的时间轴,第 i 个饼占据长度为 a[i] 的一段。

2. 按机器容量切分

把这根时间轴从起点 0 开始,每隔 T 分钟切一刀,总共切成 m 段(最后一段可能不满):

  • 第 1 段:[0, T] → 分配给机器 1
  • 第 2 段:[T, 2T] → 分配给机器 2
  • ……
  • 第 m 段:[(m-1)T, mT] → 分配给机器 m

因为 mT >= S,所以所有饼都能被放入这 m 段中。

3. 生成烙制记录

按输入顺序处理每个饼,维护当前机器编号 mach 和该机器已用时间 cur。

对于当前饼,剩余需要 need:

  • 如果 cur + need <= T,则在该机器上一次完成:记录 (饼id, mach, cur, cur+need),并更新 cur += need。
  • 否则,先在本机器上烙到 T:记录 (饼id, mach, cur, T),need -= T - cur,然后换下一台机器 mach++,cur = 0,继续处理剩余的 need。

由于 need <= mx <= T,所以一个饼最多只会被分成两段,记录数 k <= n + (m-1)。


#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct Record {
    int id1;      // 饼编号
    int id2;      // 烙饼机编号
    ll l, r;      // 时间段 [l, r)
};

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int n, m; cin >> n >> m;
    vector<ll> a(n);
    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 - 1) / m);

    vector<Record> ans;
    int mach = 1;
    ll cur = 0;

    for(int i = 0; i < n; i ++) {
        ll need = a[i];
        while(need > 0) {
            if(cur == T) {mach ++;cur = 0;}
            ll take = min(need, T - cur);
            ans.push_back({i + 1, mach, cur, cur + take});
            need -= take;
            cur += take;
        }
    }

    cout << ans.size() << '\n';
    for(auto &rec : ans) 
        cout << rec.id1 << ' ' << rec.id2 << ' '  << rec.l << ' ' << rec.r << '\n';

    return 0;
}
posted @ 2026-09-26 17:43  thenrify  阅读(15)  评论(0)    收藏  举报