这题很迷,半知半解。
这不是题解,因为我也不懂。= =
小于100行的省选题,却难到爆炸
此题做法是【斜率优化】
#include<bits/stdc++.h>
#define MAXN 50010
#define ll long long
using namespace std;
ll a[MAXN];
ll s[MAXN];
ll dp[MAXN];
ll que[MAXN];
ll n,l;
void read(ll &x){
x=0;bool flag=false;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
if(flag)x=-x;
}
double slop(ll a,ll b){return (dp[b]-dp[a]+(s[b]+l)*(s[b]+l)-(s[a]+l)*(s[a]+l))/(2.0*(s[b]-s[a]));}
void work(){
int head=1,tail=1,i;
que[1]=0;
for(i=1;i<=n;i++){
while(head<tail && slop(que[head],que[head+1])<=s[i])head++;
int k=que[head];
dp[i]=dp[k]+(s[i]-s[k]-l)*(s[i]-s[k]-l);
while(head<tail && slop(que[tail],i)<slop(que[tail-1],que[tail]))tail--;
que[++tail]=i;
}
}
int main(){
int i,j;
read(n),read(l);l++;
for(i=1;i<=n;i++){
read(a[i]);
s[i]=s[i-1]+a[i]+1;
}
work();
printf("%lld",dp[n]);
return 0;
}