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

 

你可能感兴趣的:(ZOJ)