【bzoj1597- [Usaco2008 Mar]土地购买】斜率优化
【597】[Usaco2008 Mar]土地購買
【題目描述】
有N (1 <= N <= 50,000) 塊長方形的土地. 每塊土地的長寬滿足(1 <= 寬 <= 1,000,000; 1 <= 長 <= 1,000,000). 每塊土地的價格是它的面積,但FJ可以同時購買多快土地. 這些土地的價格是它們最大的長乘以它們最大的寬, 但是土地的長寬不能交換. 如果FJ買一塊3×5的地和一塊5×3的地,則他需要付5×5=25. FJ希望買下所有的土地,但是他發(fā)現(xiàn)分組來買這些土地可以節(jié)省經(jīng)費. 他需要你幫助他找到最小的經(jīng)費。
【輸入格式】
第1行: 一個數(shù): N
第2..N+1行: 第i+1行包含兩個數(shù),分別為第i塊土地的長和寬。
【輸出格式】
求最小的可行費用。
Sample Input
4
100 1
15 15
20 5
1 100
Sample Output
500
HINT
FJ分3組買這些土地: 第一組:100×1, 第二組1×100, 第三組20×5 和 15×15 plot. 每組的價格分別為100,100,300, 總共500
?
給定一些矩形,分組購買,一組的價格是其中最大的長*最大的寬。
n<=50000
?
一開始并沒有思路。。。
?
首先,我們考慮沒有貢獻的矩形——對于x,如果存在a[y]>=a[x] && b[y]>=b[x],則x是無用的。排序去掉。
排序就先按x排序大到小,再按y排序大到小。
出現(xiàn)排序后x,y,z矩形,x能不能套y但能套z的話,那y也能套z,是不會錯的。。?
最后一定是a遞減,b遞增。
so:
f[i]=f[j]+a[j+1]*b[i]
然后用斜率優(yōu)化。
這個是把除法改成乘法的。
?
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<queue> 8 using namespace std; 9 10 typedef long long LL; 11 const int N=50010; 12 int n,pl,Q[N]; 13 LL l=0,r=0,ai,xj,bj,j,f[N]; 14 struct node{ 15 LL a,b; 16 bool bk; 17 }p[N]; 18 19 // f[i]=f[j]+a[j+1]*b[i] 20 // ai=b[i] 21 // xj=a[j+1] 22 // bj=f[j] 23 24 LL XX(int i,int j){return p[i+1].a-p[j+1].a;} 25 LL YY(int i,int j){return f[i]-f[j];} 26 double X(int i){return p[i+1].a;} 27 double Y(int i){return f[i];} 28 double find_k(int i,int j){return (Y(i)-Y(j))/(X(i)-X(j));} 29 30 bool cmp(node x,node y){ 31 if(x.a!=y.a) return x.a>y.a; 32 return x.b>y.b; 33 } 34 35 bool judge_1() 36 { 37 LL tx=XX(Q[l],Q[l+1]),ty=YY(Q[l],Q[l+1]); 38 if(tx>=0) return ty>=((-ai)*tx); 39 return ty<=((-ai)*tx); 40 } 41 42 bool judge_2(int i) 43 { 44 LL t0=YY(Q[r],Q[r-1]),t1=XX(Q[r],Q[r-1]),t2=YY(i,Q[r]),t3=XX(i,Q[r]); 45 if(t1<0) t0=-t0,t1=-t1; 46 if(t3<0) t2=-t2,t3=-t3; 47 return (t0*t3)<(t1*t2); 48 } 49 50 int main() 51 { 52 freopen("a.in","r",stdin); 53 // freopen("acquire.in","r",stdin); 54 // freopen("acquire.out","w",stdout); 55 scanf("%d",&n); 56 for(int i=1;i<=n;i++) 57 { 58 scanf("%lld%lld",&p[i].a,&p[i].b); 59 p[i].bk=1; 60 } 61 sort(p+1,p+1+n,cmp); 62 j=1; 63 for(int i=2;i<=n;i++) 64 { 65 if(p[i].a<=p[j].a && p[i].b<=p[j].b) p[i].bk=0; 66 else j=i; 67 } 68 pl=1; 69 for(int i=2;i<=n;i++) 70 if(p[i].bk) p[++pl]=p[i]; 71 72 for(int i=1;i<=pl;i++) 73 { 74 ai=p[i].b; 75 while(l<r && judge_1()) l++;/*find_k(Q[l],Q[l+1])>=(-ai)*/ 76 j=Q[l]; 77 xj=p[j+1].a; 78 bj=f[j]; 79 f[i]=ai*xj+bj; 80 while(l<r && judge_2(i)) r--;/*find_k(Q[r],Q[r-1])<find_k(i,Q[r])*/ 81 Q[++r]=i; 82 } 83 printf("%lld\n",f[pl]); 84 return 0; 85 }?
轉(zhuǎn)載于:https://www.cnblogs.com/KonjakJuruo/p/5890544.html
總結(jié)
以上是生活随笔為你收集整理的【bzoj1597- [Usaco2008 Mar]土地购买】斜率优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《知易行难》扩展练习
- 下一篇: 摘抄自知乎的redis相关