这是一个大水题
斜率优化dp
推一推式子
#include<bits/stdc++.h>
#define lca long long
using namespace std;
const int MX = 50005 ;
lca n,l,p,q[MX];
lca c[MX],dp[MX];
double getk(int pos)
{
int x=q[pos],y=q[pos-1];
return (double)(dp[x]+(c[x]*c[x])-dp[y]-(c[y]*c[y]))/(double)(c[x]-c[y]);
}
int main()
{
scanf("%lld%lld",&n,&l);
for(int i=1;i<=n;i++) scanf("%lld",&c[i]),c[i]+=c[i-1]+1;
int h=1,t=0;
q[++t]=0;
for(int i=1;i<=n;i++)
{
lca T=2*(c[i]-l-1);
while(h<t&&getk(h+1)<T) h++;
int tem=q[h];
dp[i]=dp[tem]+(c[i]-c[tem]-l-1)*(c[i]-c[tem]-l-1);
q[++t]=i;
while(h<t&&getk(t)<getk(t-1)) q[--t]=i;
}
printf("%lld\n",dp[n]);
}
心得:
1.凸包非常的好!
2.要搞清楚到底是下凸的函数还是上凸的。
这个非常重要 一定要算清楚 想清楚 把图画清楚