您的位置:首页 > 其它

【BZOJ】【P3156】【防御准备】【题解】【斜率优化】

2014-10-29 15:05 302 查看
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3156

dp方程:

reverse(a)

f[1]=a[1]

f[i]=a[i]+min(f[j]+(i-j)*(i-j-1)/2)

f[i]=a[i]+(i*i-i)/2+min(f[j]+(j*j+j)/2-ij)

是斜率优化

呃,我只会nlogn的凸包+三分怎么破……

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e6+5;
struct point{
LL x,y;
point(LL _x=0,LL _y=0):x(_x),y(_y){}
LL operator*(point oth)const{return x*oth.y-y*oth.x;}
LL operator^(point oth)const{return x*oth.x+y*oth.y;}
point operator-(point oth)const{return point(x-oth.x,y-oth.y);}
};
LL n,a[maxn];
LL f[maxn];
LL getint(){
LL res=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))res=res*10+c-'0',c=getchar();
return res;
}
struct CH{
point ch[maxn];
int m;
CH():m(0){}
void push_back(point p){
while(m>1&&(ch[m-1]-ch[m-2])*(p-ch[m-1])<=0)m--;
ch[m++]=p;
}
LL Qmin(point p){
int l=0,r=m-1;
while(r-l>2){
int mid1=l+(r-l)/3;
int mid2=r-(r-l)/3;
if((p^ch[mid1])<(p^ch[mid2]))
r=mid2;
else l=mid1;
}LL ans=1LL<<61;
for(int i=l;i<=r;i++)ans=min(ans,p^ch[i]);
return ans;
}
}C;
int main(){
n=getint();
for(LL i=1;i<=n;i++)a[i]=getint();
reverse(a+1,a+1+n);n++;
f[1]=a[1];C.push_back(point(1,f[1]+1));
for(LL i=2;i<=n;i++){
f[i]=1LL<<61;
f[i]=C.Qmin(point(-i,1))+(LL)a[i]+(LL)((LL)i*i-i)/2;
C.push_back(point(i,f[i]+(LL)(i*i+i)/2));
}cout<<min(f
,f[n-1])<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bzoj