P3195 [HNOI2008]玩具装箱TOY


第一次做斜率DP,加油!


#include<bits/stdc++.h>
using namespace std;
long long n,l,dp[51000],c[51000],f[51000],g[51000],q[51000],h,t;
double k(int j1, int j2)
{return (double) (dp[j2] + g[j2] - dp[j1] - g[j1]) / (f[j2] - f[j1]);}
int main()
{
    cin>>n>>l;
    for(int i=1;i<=n;i++)
    {cin>>c[i];c[i]+=c[i-1];f[i]=c[i]+i;g[i]=(f[i]+l+1)*(f[i]+l+1);}
    g[0]=(l+1)*(l+1);
    for(int i=1;i<=n;i++)
    {
        while(h<t&&k(q[h],q[h+1])<=2*f[i])h++;
        dp[i]=dp[q[h]]+(f[i]-f[q[h]]-l-1)*(f[i]-f[q[h]]-l-1);
        while(h<t&&k(q[t],i)<k(q[t-1],q[t]))t--;
        q[++t]=i;
    }
    cout<<dp[n];
}
原文地址:https://www.cnblogs.com/SFWR-YOU/p/11746910.html