[bzoj1597]: [Usaco2008 Mar]土地购买
斜率优化dp
从今天开始练习dp,各种dp
斜率方程:slope(a,b)=(f(a)-f(b))/(y(b+1)-y(a+1))
代码:
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 inline int read(){ 5 int x=0;char ch=' ';int f=1; 6 while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); 7 if(ch=='-'){ 8 f=-1;ch=getchar(); 9 } 10 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 11 return x*f; 12 } 13 int n,tot; 14 ll x[50001],y[50001],f[50001]; 15 int q[50001],l,r; 16 inline double slope(int a,int b){ 17 return (double)(f[a]-f[b])/(double)(y[b+1]-y[a+1]); 18 } 19 struct node{ 20 int x,y; 21 inline bool operator < (const node& b) const { 22 return (x==b.x)?y<b.y:x<b.x; 23 } 24 }a[50001]; 25 int main(){ 26 n=read(); 27 for(int i=1;i<=n;i++){ 28 a[i].x=read();a[i].y=read(); 29 } 30 sort(a+1,a+n+1); 31 for(int i=1;i<=n;i++){ 32 while(tot&&y[tot]<=a[i].y)tot--; 33 x[++tot]=a[i].x;y[tot]=a[i].y; 34 } 35 l=0,r=0; 36 for(int i=1;i<=tot;i++){ 37 while(l<r&&slope(q[l],q[l+1])<x[i])l++; 38 f[i]=f[q[l]]+y[q[l]+1]*x[i]; 39 while(l<r&&slope(q[r],i)<slope(q[r-1],q[r]))r--; 40 q[++r]=i; 41 } 42 printf("%lld",f[tot]); 43 return 0; 44 }