《算法进阶指南》--斜率优化-任务安排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;
}
收获:

浙公网安备 33010602011771号