《斜率dp》

话不多说直接上题。

P3195 [HNOI2008]玩具装箱:

 

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 5e4 + 5;
const int M = 1e6 + 5;
const int MM = 1e6;
const LL Mod = 998244353;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;

int a[N],n,L;
LL sum[N],dp[N];//dp[i] - 到第i件物品的最优价值
int Q[N];
double X(int i) {return sum[i] + i + L + 1;}
double Y(int i) {return dp[i] + X(i) * X(i);}
double A(int i) {return sum[i] + i;}
double Kline(int i,int j) {return (Y(j) - Y(i)) / (X(j) - X(i));}
int main() {
    scanf("%d %d",&n,&L);
    for(int i = 1;i <= n;++i) scanf("%d",&a[i]),sum[i] = sum[i - 1] + a[i];
    int head = 1,tail = 1;
    for(int i = 1;i <= n;++i) {
        while(head < tail && Kline(Q[head],Q[head + 1]) < 2 * A(i)) head++;
        dp[i] = dp[Q[head]] + (A(i) - X(Q[head])) * (A(i) - X(Q[head]));
        while(head < tail && Kline(Q[tail - 1],Q[tail]) > Kline(Q[tail - 1],i)) tail--;
        Q[++tail] = i;
    }

    printf("%lld\n",dp[n]);
    system("pause");
    return 0;
}
View Code

 

posted @ 2021-08-20 17:38  levill  阅读(19)  评论(0编辑  收藏  举报