【无聊放个模板系列】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

posted @ 2016-11-18 08:26  konjak魔芋  阅读(287)  评论(0编辑  收藏  举报