ZJOI2007仓库建设

斜率优化

而且完美的双单调

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1000010
 4 #define rep(a,b,c) for(register int (a)=(b);(a)<=(c);++(a))
 5 #define RG register
 6 #define IL inline
 7 #define mst(a,b) memset((a),(b),sizeof((a)))
 8 #define PN printf("\n")
 9 #define PD(a) printf(" %d ",(a))
10 IL int isitdigit(char c){    return c<='9'&&c>='0';    }
11 IL int read()
12 {
13     RG int s;RG char c;
14     while(!isitdigit(c=getchar()));
15     for(s=c-'0';isitdigit(c=getchar());s=(s<<1)+(s<<3)+c-'0');
16     return s;
17 }
18 int n;
19 long long k[N],c[N],sum[N],sump[N];
20 long long f[N];
21 int head=1,tail=0;
22 struct point{
23     long long  x,y;
24     point(long long a=0,long long b=0):x(a),y(b){}
25     IL const point operator - (const point another)
26     const{    return (point){x-another.x,y-another.y};    }
27 }que[N];
28 IL long long det(const point a,const point b)
29 {    return a.x*b.y-a.y*b.x;    }
30 IL int judge(const point a,int b)
31 {    return a.y<b*a.x;    }
32 int main()
33 {
34     //freopen("thu.in","r",stdin);
35     scanf("%d",&n);
36     rep(i,1,n) 
37     {
38         k[i]=read();
39         RG int p=read();
40         c[i]=read();
41         sum[i]=sum[i-1]+p,sump[i]=sump[i-1]+k[i]*p;
42     }
43     rep(i,0,n)
44     {
45         while(head<tail&&judge(que[head+1]-que[head],k[i])) head++;
46         f[i]=que[head].y-k[i]*que[head].x+c[i]+k[i]*sum[i]-sump[i];
47         point now(sum[i],f[i]+sump[i]);
48         while(head<tail&&det(que[tail]-que[tail-1],now-que[tail])<=0) tail --;
49         que[++tail]=now;
50     }
51     printf("%lld",f[n]);
52     return 0;
53 }

 

posted @ 2018-06-21 17:25  咸鱼炒蒟蒻  阅读(105)  评论(0编辑  收藏  举报