题目大意:一条线上N个(检查)点,编号1~N,一个点j上可以建一个守卫塔花费为a[j],也可以选择放个木偶(为什么会是木偶= =),花费是这个点右边建的第一个守卫塔i到这个点的距离,即i-j。问最小花费
题解:斜率优化,随便推推式子
我的收获:233333
#include <bits/stdc++.h>
using namespace std;
#define N 1000005
#define ll long long
int n,deq[N];
ll f[N],a[N];
inline ll sqr(ll x){return x*x;}
inline ll up(ll x,ll y){return 2ll*(f[x]-f[y])+sqr(x)-sqr(y)+x-y;}
inline ll down(ll x,ll y){return (x-y);}
inline double k(ll x,ll y){return (double)up(x,y)/down(x,y);}
inline ll calc(ll x,ll y){return f[x]+(y-x)*(y-x-1)/2+a[y];}
void work()
{
int l=1,r=0;deq[++r]=0;
for(int i=1;i<=n;i++){
while(l<r&&k(deq[l],deq[l+1])<=2ll*i) l++;
f[i]=calc(deq[l],i);
while(l<r&&k(deq[r-1],deq[r])>k(deq[r],i)) r--;
deq[++r]=i;
}
printf("%lld\n",f[n]);
}
void init()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
}
int main()
{
init();
work();
return 0;
}