码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ】【1597】【USACO 2008 Mar】土地购买

时间:2015-03-12 18:51:04      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

DP/斜率优化


  Orz Hzwer……

  想到排序了,但没想到其实可以将序列转化为x递增且y递减的序列……因为x是递增的,若y[i]>y[i-1]那么第i-1个就足够小……以至于可以在搞定第 i 个的同时顺便带走……

  这次仔细写一下斜率优化的过程吧~

  方程:$ f[i]=min\{ f[j]+x[i]*y[j+1] \} $

  若 $j>k$ 且 决策$j$更优,则有:\[ \begin{aligned} {f[j]+x[i]*y[j+1]} &<  {f[k]+x[i]*y[k+1]}  \\ {f[j]-f[k]} &<  {x[i]*(y[k+1]-y[j+1])} \\ {\frac{ f[j]-f[k] }{ y[k+1]-y[j+1] }} &<  {x[i]} \end{aligned} \]

  至此我们就可以用单调队列来维护决策序列了(一个凸壳)

技术分享
 1 /**************************************************************
 2     Problem: 1597
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:108 ms
 7     Memory:3036 kb
 8 ****************************************************************/
 9  
10 //BZOJ 1597
11 #include<cmath>
12 #include<vector>
13 #include<cstdio>
14 #include<cstring>
15 #include<cstdlib>
16 #include<iostream>
17 #include<algorithm>
18 #define rep(i,n) for(int i=0;i<n;++i)
19 #define F(i,j,n) for(int i=j;i<=n;++i)
20 #define D(i,j,n) for(int i=j;i>=n;--i)
21 #define pb push_back
22 using namespace std;
23 int getint(){
24     int v=0,sign=1; char ch=getchar();
25     while(ch<0||ch>9){ if (ch==-) sign=-1; ch=getchar();}
26     while(ch>=0&&ch<=9){ v=v*10+ch-0; ch=getchar();}
27     return v*=sign;
28 }
29 const int N=50010,INF=~0u>>2;
30 typedef long long LL;
31 /******************tamplate*********************/
32  
33 struct node{
34     int x,y;
35     bool operator < (const node&b)const{
36         return x<b.x || (x==b.x && y<b.y);
37     }
38 }a[N];
39 LL f[N],x[N],y[N];
40 int q[N];
41 double slop(int a,int b){
42     return double(f[b]-f[a])/(y[a+1]-y[b+1]);
43 }
44 int main(){
45     int n=getint(),m=0;
46     F(i,1,n) a[i].x=getint(),a[i].y=getint();
47     sort(a+1,a+n+1);
48     F(i,1,n){
49        while(m && a[i].y>=y[m]) m--;
50        x[++m]=a[i].x; y[m]=a[i].y;
51     }
52     int l=0,r=0;
53     F(i,1,m){
54         while(l<r && slop(q[l],q[l+1])<x[i])l++;
55         int t=q[l];
56         f[i]=f[t]+y[t+1]*x[i];
57         while(l<r && slop(q[r],i)<slop(q[r-1],q[r]))r--;
58         q[++r]=i;
59     }
60     printf("%lld\n",f[m]);
61     return 0;
62 }
View Code

 

【BZOJ】【1597】【USACO 2008 Mar】土地购买

标签:

原文地址:http://www.cnblogs.com/Tunix/p/4332827.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!