# bzoj1597/luogu2900 土地购买 (斜率优化dp)

f[i]=min{f[j]+x[i]*maxy[j+1..i]}

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #define LL long long int
5 using namespace std;
6 const int maxn=50050;
7
8 int rd(){
9     int x=0;char c=getchar();
10     while(c<'0'||c>'9') c=getchar();
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x;
13 }
14
15 struct Node{
16     int x,y;
17 }p[maxn];
18 int N,q[maxn],h,t;
19 LL x[maxn],y[maxn],f[maxn];
20 bool deled[maxn];
21
22 inline bool cmp(Node a,Node b){
23     return a.x==b.x?a.y<b.y:a.x<b.x;
24 }
25
26 inline bool judge1(int j1,int j2,int i){
27     return f[j1]-f[j2]<x[i]*(y[j2+1]-y[j1+1]);
28 }
29 inline bool judge2(int j1,int j2,int j3){
30     return (f[j1]-f[j2])*(y[j2+1]-y[j3+1])>(f[j2]-f[j3])*(y[j1+1]-y[j2+1]);
31 }
32
33 int main(){
34     int i,j,k;
35     N=rd();
36     for(i=1;i<=N;i++) p[i].x=rd(),p[i].y=rd();
37     sort(p+1,p+N+1,cmp);
38     for(i=N;i;i=j){
39         for(j=i-1;j&&p[j].y<p[i].y;j--) deled[j]=1;
40     }for(i=1,j=0;i<=N;i++){
41         if(!deled[i]) x[++j]=p[i].x,y[j]=p[i].y;
42     }N=j;
43     q[h=t=1]=0;
44     for(i=1;i<=N;i++){
45         while(h<t&&!judge1(q[h],q[h+1],i)) h++;
46         f[i]=f[q[h]]+x[i]*y[q[h]+1];
47         while(h<t&&!judge2(q[t-1],q[t],i)) t--;
48         q[++t]=i;
49     }printf("%lld",f[N]);
50 }

posted @ 2018-08-10 21:08  Ressed  阅读(132)  评论(0编辑  收藏  举报