【无聊放个模板系列】BZOJ 1597 斜率优化
STL 双向队列DEQUE版本
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 #define Maxn 50010 10 #define LL long long 11 12 struct node 13 { 14 LL x,y; 15 }t[Maxn]; 16 17 bool cmp(node x,node y) {return (x.x==y.x)?(x.y<y.y):(x.x<y.x);} 18 19 deque<node > q; 20 LL f[Maxn]; 21 22 bool check(node x,node y,LL k) 23 { 24 return (y.y-x.y)<=k*(y.x-x.x); 25 } 26 27 bool check2(node x,node y,node z) 28 { 29 return (y.y-x.y)*(z.x-y.x)>=(y.x-x.x)*(z.y-y.y); 30 } 31 32 int main() 33 { 34 LL n; 35 scanf("%lld",&n); 36 for(LL i=1;i<=n;i++) scanf("%lld%lld",&t[i].x,&t[i].y); 37 sort(t+1,t+1+n,cmp); 38 /*LL p=1; 39 for(LL i=2;i<=n;i++) if(t[i].x>t[p].x&&t[i].y<t[p].y) t[++p]=t[i];*/ 40 41 42 LL p=0; 43 for(LL i=1;i<=n;i++) 44 { 45 while(p>0&&t[i].y>=t[p].y) p--; 46 t[++p]=t[i]; 47 } 48 49 while(!q.empty()) q.pop_back(); 50 node ft;ft.x=t[1].y,ft.y=0;q.push_front(ft); 51 for(LL i=1;i<=p;i++) 52 { 53 while(q.size()>1) 54 { 55 node x=q.front();q.pop_front(); 56 if(!check(x,q.front(),-t[i].x)) {q.push_front(x);break;} 57 } 58 node tt; 59 f[i]=q.front().y+t[i].x*q.front().x; 60 tt.x=t[i+1].y;tt.y=f[i]; 61 while(q.size()>1) 62 { 63 node x=q.back();q.pop_back(); 64 if(!check2(tt,x,q.back())) {q.push_back(x);break;} 65 } 66 q.push_back(tt); 67 // printf("%d\n",f[i]); 68 } 69 printf("%lld\n",f[p]); 70 return 0; 71 }
手打队列版本
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 #define Maxn 50010 10 #define LL long long 11 12 struct hp 13 { 14 LL x,y; 15 }a[Maxn]; 16 17 bool cmp(hp x,hp y) {return (x.x==y.x)?(x.y<y.y):(x.x<y.x);} 18 19 struct node 20 { 21 LL x,y; 22 }t[Maxn]; 23 24 LL f[Maxn]; 25 26 bool check(int x,int y,int k) 27 { 28 LL kk=k; 29 return kk*(t[x].x-t[y].x)<=t[x].y-t[y].y; 30 } 31 32 bool check2(int x,int y,int z) 33 { 34 return (t[y].x-t[z].x)*(t[x].y-t[y].y)<=(t[x].x-t[y].x)*(t[y].y-t[z].y); 35 } 36 37 int main() 38 { 39 int n; 40 scanf("%d",&n); 41 for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y); 42 sort(a+1,a+1+n,cmp); 43 int cnt=0; 44 for(int i=1;i<=n;i++) 45 { 46 while(cnt>0&&a[i].y>=a[cnt].y) cnt--; 47 a[++cnt]=a[i]; 48 } 49 int len=0,st; 50 t[++len].x=a[1].y;t[len].y=0;st=1; 51 for(int i=1;i<=cnt;i++) 52 { 53 while(st<len&&check(st,st+1,-a[i].x)) st++; 54 f[i]=a[i].x*t[st].x+t[st].y; 55 t[0].x=a[i+1].y;t[0].y=f[i]; 56 while(st<len&&check2(len-1,len,0)) len--; 57 t[++len]=t[0]; 58 // printf("%lld\n",f[i]); 59 } 60 printf("%lld\n",f[cnt]); 61 return 0; 62 }
斜率优化
2016-11-18 08:30:47