bzoj 1957 土地购买

这道题是我斜率优化第一题,对此做一个纪念。

首先进行一遍筛选,然后动态规划表达式很快就写出来了f(i)=min(f(i)+b[j+1]*a[i])

然后就要进行斜率优化了,显然这里边所有东西都是单调的,所以只需要维护单调队列即可。

cal函数计算的是斜率,具体看代码吧(参考别人),以后要多加练习。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 long long f[500005];
 6 int a[500005];
 7 int n;
 8 long long u[50005],v[50005];
 9 struct node
10 {
11     long long x,y;
12 }p[50005];
13 int q[50005];
14 int head,tail;
15 bool cmp(int x,int y)
16 {
17     if(u[x]!=u[y])return u[x]<u[y];
18     else return v[x]<v[y];
19 }
20 int m;
21 double cal(int x,int y)
22 {
23     return (double)(f[y]-f[x])/(p[x+1].y-p[y+1].y);
24 }
25 int main()
26 {
27     scanf("%d",&n);
28     for(int i=1;i<=n;i++)
29     {
30         a[i]=i;
31         scanf("%lld%lld",&u[i],&v[i]);
32     }
33     sort(a+1,a+n+1,cmp);
34     for(int i=1;i<=n;i++)
35     {
36         while(m && p[m].y<=v[a[i]])m--;
37         m++;
38         p[m].x=u[a[i]];
39         p[m].y=v[a[i]];
40     }
41     n=m;
42     for(int i=1;i<=n;i++)
43     {
44         while(head<tail && cal(q[head],q[head+1])<p[i].x)head++;
45         int t=q[head];
46         f[i]=f[t]+p[t+1].y*p[i].x;
47         while(head<tail && cal(q[tail-1],q[tail])>cal(q[tail],i))tail--;
48         q[++tail]=i;
49     }
50     printf("%lld\n",f[n]);
51     return 0;
52 }
53     
View Code

 

posted @ 2014-08-23 15:05  溪桥,吾愿  阅读(177)  评论(0编辑  收藏  举报