《算法进阶指南》--斜率优化-任务安排2

斜率优化的转移方程以一段区间为转移起点取极值,设转移起点为j,转移目标为i,将由i决定的值看作常数,由j决定的值看作变量,可以化成线性方程y=ax+b的形式,并且转移终点f[i]也就是我们需要求的值需要表示“截距”
,同时需要表示x的变量单调递增。每一个j都对于直角坐标系中一个点,由于在转移时i是固定的,a可以直接求得,则每一个j对应一个截距,根据截距大小求得j为何值时f[i]取极值。

const int N = 300000;
int n, s;
int t[N + 10], c[N + 10];
int f[N + 10];
int pret[N + 10], prec[N + 10];
int dq[N + 10];
int ll = 0, rr = 0;
void solve()
{
    cin >> n >> s;
    for (int i = 1; i <= n; i++)
    {
        cin >> t[i] >> c[i];
        pret[i] = pret[i - 1] + t[i];
        prec[i] = prec[i - 1] + c[i];
    }
    dq[0] = 0;
    for (int i = 1; i <= n; i++)
    {
        double nowtan = s + pret[i];
        while (ll < rr && (f[dq[ll + 1]] - f[dq[ll]]) * 1.0 / (prec[dq[ll + 1]] - prec[dq[ll]]) * 1.0 <= nowtan)
        {
            ll++;
        }
        int j = dq[ll];
        f[i] = f[j] - (s + pret[i]) * prec[j] + pret[i] * prec[i] + s * prec[n];

        while (ll < rr && (f[i] - f[dq[rr]]) * 1.0 / (prec[i] - prec[dq[rr]]) * 1.0 <= (f[dq[rr]] - f[dq[rr - 1]]) * 1.0 / (prec[dq[rr]] - prec[dq[rr - 1]]) * 1.0)
        {
            rr--;
        }
        dq[++rr] = i;
    }
    cout << f[n] << endl;
}

收获:

posted @ 2025-07-10 15:45  青一凡  阅读(3)  评论(0)    收藏  举报