《斜率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; }