比利♂海灵顿
2021-03-15 20:47:32
斜率优化模板题, 是 算法竞赛进阶指南-李煜东
的斜率优化例题, 关于斜率优化的内容, 可以在这里找到
斜率优化
题目直通车
加强版
试求完成所有任务的最小花费
设计状态,
用
写出方程, 前
整理得
得到以
虽然本题不用斜优, 为什么不复制加强版的代码呢
struct Ms {
long long C, T, SumC, SumT, f;
}M[5005]; // 任务属性
struct Hull {
long long x, y;
unsigned Ad;
}H[5005], *Now, Then; // 下凸壳
unsigned n, l(1), r(1);
long long S, Cst;
int main() {
n = RD();
S = RD();
M[0].SumT = S;
for (register unsigned i(1); i <= n; ++i) {
M[i].T = RD();
M[i].C = RD();
M[i].SumT = M[i - 1].SumT + M[i].T;
M[i].SumC = M[i - 1].SumC + M[i].C; //预处理
}
Cst = S * M[n].SumC; // 截距中的一项常数
for (register unsigned i(1); i <= n; ++i) {
while (l < r && ((H[l + 1].y - H[l].y) < M[i].SumT * (H[l + 1].x - H[l].x))) {
++l; // 弹出过气决策点
}
M[i].f = M[H[l].Ad].f + (M[i].SumC - M[H[l].Ad].SumC) * M[i].SumT + Cst - M[i].SumC * S; // 转移
Then.Ad = i;
Then.x = M[i].SumC;
Then.y = M[i].f; // 求新点坐标
while (l < r && ((Then.y - H[r].y) * (H[r].x - H[r - 1].x) <= (H[r].y - H[r - 1].y) * (Then.x - H[r].x))) {
--r; // 维护下凸
}
H[++r] = Then; // 入队
}
printf("%lld\n", M[n].f);
return Wild_Donkey;
}
因为
Hull *Binary (unsigned L, unsigned R, const long long &key) {
if(L == R) {
return H + L;
}
unsigned M((L + R) >> 1), M_ = M + 1;
if((H[M_].y - H[M].y) < key * (H[M_].x - H[M].x)) {//Key too big
return Binary(M_, R, key);
}
return Binary(L, M, key);
}