HYSBZ - 1010 玩具装箱toy dp+斜率优化

题意:略

思路:见上篇博客详解https://blog.csdn.net/xiang_6/article/details/81479453

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int maxn = 5e4 + 7;
ll dp[maxn];
ll sum[maxn];
int n;
ll m;
int qu[maxn];

ll get1(int i, int j) {
    return (dp[i]+(sum[i]+i)*(sum[i]+i) - dp[j]-(sum[j]+j)*(sum[j]+j));
}
ll get2(int i, int j) {
    return ((sum[i]+i)-(sum[j]+j));
}
bool is_ok(int k, int j, int i) {
    return (get1(i,j)*get2(j,k) <= get1(j,k)*get2(i,j) );
}
ll X(int i) {
    return (sum[i]+i-1-m);
}
int main() {
    while(scanf("%d%lld", &n, &m) == 2) {
        for(int i = 1; i <= n; ++i) {
            scanf("%lld", &sum[i]);
        }
        qu[0] = sum[0] = dp[0] = 0;
        for(int i = 1; i <= n; ++i) {
            sum[i] += sum[i-1];
        }
        int idl = 0, idr = 0;
        for(int i = 1; i <= n; ++i) {
            while(idl < idr && get1(qu[idl+1],qu[idl])<=2*X(i)*get2(qu[idl+1],qu[idl])) idl++;
            int j = qu[idl];
            dp[i] = dp[j] + (sum[i]-sum[j]+i-j-1-m)*(sum[i]-sum[j]+i-j-1-m);
            while(idr>idl && is_ok(qu[idr-1],qu[idr],i)) idr--;
            qu[++idr] = i;
        }
        printf("%lld\n", dp[n]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xiang_6/article/details/81480882
今日推荐