如在任务安排(P5785/P2365),这是一道斜率优化的例题了。
但是用 O(n2) 的程序(可以通过 P2365):
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5005;
int n, s, t[N], c[N], f[N];
signed main(){
memset(f, 0x3f, sizeof(f));
scanf("%lld%lld", &n, &s);
for(int i = 1; i <= n; i++){
scanf("%lld%lld", &t[i], &c[i]);
t[i] += t[i - 1];
c[i] += c[i - 1];
}
f[0] = 0;
for(int i = 1; i <= n; i++){
for(int j = 0; j < i; j++){
f[i] = min(f[i], f[j] + (t[i] - t[j] + s) * (c[n] - c[j]));
}
//printf("f[%lld]=%lld\n", i, f[i]);
}
printf("%lld\n", f[n]);
return 0;
}
(时间贡献先算,不好说明)
程序中的式子并且删除注释可以得到,样例中 f1=30,f2=75,f3=125。
而转移方程按照斜率优化的方式转移可以得到:
fj=(s+ti)cj+fi−ti×ci−s×cn,这条式子也和书中对上了。(其中 c,t 的数组求过前缀和)
那么,在计算 f3 的时候前有三个点 A(0,0),B(3,30),C(5,75),发现 kAB=10,kBC=22.5。
对于 f3,它的斜率是 s+t3=9<10,说明 3 应该从决策点 A 转移过来,而不是样例解释里的 C 点。
而事实上 C 点转移是正确的。
想问以下蒟蒻的推导过程那里错了?