【题解】hdu3507:Print Article

原题传送门
斜率优化
s i = ∑ j = 1 i c j s_i=\sum_{j=1}^{i}c_j si=j=1icj
可以写出一个非常显然的dp方程: d p i = m i n ( d p j + ( s i − s j ) 2 ) + M dp_i=min(dp_j+(s_i-s_j)^2)+M dpi=min(dpj+(sisj)2)+M
接下来固定套路
设两个决策 x , y ( x > y ) x,y(x>y) x,y(x>y),如果x比y更优必须满足
d p x + ( s i − s x ) 2 &lt; d p y + ( s i − s y ) 2 dp_x+(s_i-s_x)^2&lt;dp_y+(s_i-s_y)^2 dpx+(sisx)2<dpy+(sisy)2
化简得 ( d p x − s x 2 ) − ( d p y − s y 2 ) 2 ( s x − s y ) &lt; s i \frac{(dp_x-s_x^2)-(dp_y-s_y^2)}{2(s_x-s_y)}&lt;s_i 2(sxsy)(dpxsx2)(dpysy2)<si
然后单调队列维护就行了

结果,我死活过不了,莫名其妙的wa掉也是一脸懵逼
去网上找了篇题解对拍没有问题,那就算了吧
Code:

#include <bits/stdc++.h>
#define maxn 500010
#define LL long long
using namespace std;
LL n, m, s[maxn], q[maxn], dp[maxn];

inline LL read(){
    LL s = 0, w = 1;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    return s * w;
}

double slope(int x, int y){ return 1.0 * (dp[x] + s[x] * s[x] - dp[y] - s[y] * s[y]) / 2LL / (s[x] - s[y]); }

int main(){
    while (scanf("%d%d", &n, &m) == 2){
        for (int i = 1; i <= n; ++i) s[i] = read(), s[i] += s[i - 1];
        int h = 0, t = 0;
        for (int i = 1; i <= n; ++i){
            while (h < t && slope(q[h + 1], q[h]) < s[i]) ++h;
            dp[i] = dp[q[h]] + (s[i] - s[q[h]]) * (s[i] - s[q[h]]) + m;
            while (h < t && slope(q[t], q[t - 1]) > slope(i, q[t])) --t;
            q[++t] = i;
        }
        printf("%lld\n", dp[n]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值