APIO2010 特别行动队

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

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

代码:

#include <bits/stdc++.h>
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 (l<r && cal (q[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 (l<r && cal (q[r-1], q[r])>cal (q[r], i)) --r;
        q[++r] = i;
    } printf ("%lld\n", f[n]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值