APIO2010 特别行动队

https://www.luogu.org/problem/show?pid=3628 特别行动队

可以说是斜率优化dp的模板题,50分的方程很容易写出,先推导函数然后用单调队列维护上凸壳。

代码:

#include 
using namespace std;
typedef long long LL;
const int N = 1000005;
int q[2*N], a, b, c; LL f[N], s[N];
double cal (int x, int y) {
    LL sdt = (LL)s[y]*s[y]-s[x]*s[x]; LL dt = (LL)s[y]-s[x];
    LL dty = (LL)f[y]-f[x]+a*sdt-b*dt; LL dtx = (LL)2*a*dt;
    return 1.0*dty/dtx;
}
int main () {
    int n, x, l = 0, r = 0;
    scanf ("%d%d%d%d", &n, &a, &b, &c);
    for (int i = 1; i <= n; ++ i) {
        scanf ("%d", &x); s[i] = s[i-1]+x;
    }
    for (int i = 1; i <= n; ++ i) {
        while (lq[l], q[l+1])<s[i]) ++l;
        LL dt = (LL)s[i]-s[q[l]]; LL dts = (LL)dt*dt;
        f[i] = (LL)f[q[l]]+a*dts+b*dt+c;
        while (lq[r-1], q[r])>cal (q[r], i)) --r;
        q[++r] = i;
    } printf ("%lld\n", f[n]);
    return 0;
}

你可能感兴趣的:(APIO2010 特别行动队)