3156: 防御准备
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2396 Solved: 1015
[Submit][Status][Discuss]
Description
Input
第一行为一个整数N表示战线的总长度。
第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai。
Output
共一个整数,表示最小的战线花费值。
Sample Input
10
2 3 1 5 4 5 6 3 1 2
Sample Output
18
HINT
1<=N<=10^6,1<=Ai<=10^9
Source
基础斜率优化。。
#include<bits/stdc++.h>
#define ll long long
#define maxn 1000005
using namespace std;
struct node{
ll x,y;
node operator -(const node &u)const{
return (node){x-u.x,y-u.y};
}
}q[maxn],point;
int hd,tl,n,a[maxn];
ll f[maxn],xl;
inline int read(){
int x=0; char ch=getchar();
for(;!isdigit(ch);ch=getchar());
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x;
}
inline ll Xmul(node x,node y){
return x.x*y.y-x.y*y.x;
}
inline ll calc(node x,ll XL){
return x.y-x.x*XL;
}
inline void dp(){
q[tl=hd=1]=(node){0,0};
for(int i=1;i<=n;i++){
xl=i<<1ll;
while(hd<tl&&calc(q[hd+1],xl)<calc(q[hd],xl)) hd++;
f[i]=calc(q[hd],xl)-i+i*(ll)i+a[i];
point=(node){i,f[i]+i*(ll)i+i};
while(hd<tl&&Xmul(point-q[tl],q[tl]-q[tl-1])>=0) tl--;
q[++tl]=point;
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
a[i]=read();
a[i]<<=1;
}
dp();
printf("%lld
",f[n]>>1);
return 0;
}