关于斜率优化
  • 板块灌水区
  • 楼主huangrenheluogu
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/12/1 14:59
  • 上次更新2023/12/1 19:04:22
查看原帖
关于斜率优化
461359
huangrenheluogu楼主2023/12/1 14:59

如在任务安排(P5785/P2365),这是一道斜率优化的例题了。

但是用 O(n2)O(n^2) 的程序(可以通过 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=125f_1=30,f_2=75,f_3=125。

而转移方程按照斜率优化的方式转移可以得到:

fj=(s+ti)cj+fi−ti×ci−s×cnf_j=(s+t_i)c_j+f_i-t_i\times c_i-s\times c_n,这条式子也和书中对上了。(其中 c,tc,t 的数组求过前缀和)

那么,在计算 f3f_3 的时候前有三个点 A(0,0),B(3,30),C(5,75)A(0,0),B(3,30),C(5,75),发现 kAB=10,kBC=22.5k_{AB}=10,k_{BC}=22.5。

对于 f3f_3,它的斜率是 s+t3=9<10s+t_3=9<10,说明 33 应该从决策点 AA 转移过来,而不是样例解释里的 CC 点。

而事实上 CC 点转移是正确的。

想问以下蒟蒻的推导过程那里错了?

2023/12/1 14:59
加载中...