題目傳送門
在\(acwing\)
\(301\) 任務安排\(2\)中,我們給出了任務安排問題的斜率優化的解法,因為斜率\(k = st[i] + s\)是單調遞增的(直線與橫軸的夾角遞增),所以佇列中小於當前\(k\)的斜率一定小於後面的\(k\),於是我們在查詢第乙個大於\(k\)的斜率時將小於\(k\)的斜率都刪除了,從而保證了\(o(n)\)的時間複雜度。
但是本題的\(t_i\)可能是負數,儘管時間是負數設定得有些不合理,我們只能暫且認為它是合理的,\(t_i\)是負數時,\(k = st[i] + s\)就未必單調遞增了,因為字首和不一定單調遞增了,這意味著,後面的\(k\)可能小於之前的\(k\),我們不應該在尋找第乙個大於\(k\)的斜率時刪掉小於\(k\)的斜率了,因為後面的\(k\)還可能用到,但是不刪除小於\(k\)的斜率,意味著每次尋找\(j\)都需要從堵頭找起,時間複雜度最壞可能是平方級別的,為此我們在找第乙個大於\(k\)的斜率時,只能對佇列中的斜率做二分查詢,用\(o(nlog_n)\)的時間複雜度去解決本題了。本題的其它**與上題一致,故分析過程可以參考上題,唯一修改的地方就是將原來出隊頭的**修改為二分找\(j\)的**了。
#include using namespace std;
typedef long long ll;
const int n = 300010;
int n, s;
ll st[n], sc[n];
ll f[n];
int q[n];
int main()
int j = q[l];
f[i] = f[j] - (st[i] + s) * sc[j] + st[i] * sc[i] + s * sc[n];
while (hh < tt && (double) (f[q[tt]] - f[q[tt - 1]]) * (sc[i] - sc[q[tt - 1]]) >=
(double) (f[i] - f[q[tt - 1]]) * (sc[q[tt]] - sc[q[tt - 1]]))
tt--;
q[++tt] = i;
}printf("%lld\n", f[n]);
return 0;
}
AcWing 302 任務安排3
題目描述 有 n 個任務排成乙個序列在一台機器上等待執行,它們的順序不得改變。機器會把這 n 個任務分成若干批,每一批包含連續的若干個任務。從時刻0開始,任務被分批加工,執行第 i 個任務所需的時間是 ti。另外,在每批任務開始前,機器需要 s 的啟動時間,故執行一批任務所需的時間是啟動時間 s 加...
AcWing 300 任務安排
樣例 5個任務,每個任務的啟動時間是1 1 3 4 2 1 3 2 3 3 4 接下來算費用 第一批的費用總和是3 2 3 8 總的花費就是 8 9 72 第二批的費用總和是3 4 7 7 13 91 72 91 163 最優解是153,看來這麼劃分不是最優解,好,題目理解完畢。使用費用提前計算的思...
NKOI 1047 任務安排
任務安排 time limit 1000ms memory limit 65536k total submit 143 accepted 70 description n個任務排成乙個序列在一台機器上等待完成 順序不得改變 這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批...