首页 > 其他 > 详细

BZOJ 1010. [HNOI2008]玩具装箱toy

时间:2020-01-23 14:38:34      阅读:80      评论:0      收藏:0      [点我收藏+]

$dp[i]$ 表示以 $i$ 物品为结尾的最小费用

$dp[i] = min(dp[j] + (j - i + \sum c_k - l)^2)$

斜率优化一下即可。

技术分享图片
#include <bits/stdc++.h>
#define ll long long
using namespace std;
 
const int N = 5e4 + 7;
ll sum[N], l, c[N], dp[N];
int que[N], n;
 
template <class T>
inline T sqr (T a) {
    return a * a;
}
 
inline ll X(int i) {
    return sum[i];
}
 
inline ll Y(int i) {
    return dp[i] + sqr(sum[i]) + 2 * l * sum[i];
}
 
inline double K(int i, int j) {
    return 1.0 * (Y(i) - Y(j)) / (X(i) - X(j));
}
 
int main() {
    scanf("%d%lld", &n, &l);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &c[i]), sum[i] = sum[i - 1] + c[i];
    for (int i = 1; i <= n; i++)
        sum[i] += i;
    int head = 1, tail = 1;
    l++;
    for (int i = 1; i <= n; i++) {
        while (head < tail && K(que[head], que[head + 1]) < 2 * sum[i]) head++;
        int j = que[head];
        dp[i] = dp[j] + sqr(sum[i] - sum[j] - l);
        while (head < tail && K(que[tail - 1], que[tail]) > K(que[tail], i)) tail--;
        que[++tail] = i;
    }
    printf("%lld\n", dp[n]);
    return 0;
}
View Code

BZOJ 1010. [HNOI2008]玩具装箱toy

原文:https://www.cnblogs.com/Mrzdtz220/p/12230569.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!