10 個任務,5 條流水線。每任務在各流水線上佔用特定時間('X' 表示佔用)。任務可錯開啟動,求完成所有任務的最短總時間。
w[5] 表示單個任務在各流水線的佔用模式(第 k 位為 1 表示佔用第 k 個時間單位)。s[5] 表示當前所有已啟動任務在各流水線的佔用情況(位掩碼 OR 合併)。(s[i] >> k) & w[i] == 0 對所有流水線成立。jump[] 存儲所有滿足 judge(w, k) 的 k 值(相對啟動間隔)。sum + 剩餘任務數 × jump[0] (最小合法間隔) ≥ ans → 剪枝。
void dfs(int *s, int depth, int sum) {
if (sum + jump[0] * (10 - depth) > ans) return; // 剪枝 2
if (depth == 10) { ans = min(ans, sum); return; }
for (int k : jump) {
if (judge(s, k)) {
int ns[5];
for (int i=0;i<5;i++) ns[i] = (s[i] >> k) | w[i]; // 更新狀態
dfs(ns, depth+1, sum + k);
}
}
}
第一個任務在第 0 時刻啟動,初始狀態 s = w,depth=1,sum=n(任務本身長度)。
狀態空間極小(5 條線,任務模式固定),剪枝極其有效,瞬間求解。