1597: [Usaco2008 Mar]土地购买
Submit: 6388 Solved: 2452
[Submit][Status][Discuss]
Description
农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <
= 1,000,000; 1 <= 长 <= 1,000,000). 每块土地的价格是它的面积,但FJ可以同时购买多快土地. 这些土地的价
格是它们最大的长乘以它们最大的宽, 但是土地的长宽不能交换. 如果FJ买一块3x5的地和一块5x3的地,则他需要
付5x5=25. FJ希望买下所有的土地,但是他发现分组来买这些土地可以节省经费. 他需要你帮助他找到最小的经费.
Input
* 第1行: 一个数: N
* 第2..N+1行: 第i+1行包含两个数,分别为第i块土地的长和宽
Output
* 第一行: 最小的可行费用.
Sample Input
4
100 1
15 15
20 5
1 100
输入解释:
共有4块土地.
100 1
15 15
20 5
1 100
输入解释:
共有4块土地.
Sample Output
500
FJ分3组买这些土地:
第一组:100x1,
第二组1x100,
第三组20x5 和 15x15 plot.
每组的价格分别为100,100,300, 总共500.
FJ分3组买这些土地:
第一组:100x1,
第二组1x100,
第三组20x5 和 15x15 plot.
每组的价格分别为100,100,300, 总共500.
首先排序,先比较x 后比较y,排序后x递增 y递增
然后处理一遍,去掉可以打包一起买的土地
进行斜率优化:
\[\frac{f[j]-f[k]}{y[k+1]-y[j+1]}<x[i]\]
今天彻底理解队尾处理了,有两种情况
1、如果slope(q[r-1],q[r])<x[q[r]],则q[r]比q[r-1]更优,而slope(q[r],i)更小,还是取i
2、如果slope(q[r-1],q[r])>x[q[r]],则q[r-1]更优,还是不取q[r],以i取代
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 6 #define LL long long 7 const int MAXN=50005; 8 9 struct MAT 10 { 11 int x,y; 12 }a[MAXN]; 13 14 int n,tot,l,r; 15 LL x[MAXN],y[MAXN],q[MAXN],f[MAXN]; 16 17 bool cmp(MAT A,MAT B) 18 { 19 return A.x!=B.x?A.x<B.x:A.y<B.y; 20 } 21 22 double slope(int k,int j) 23 { 24 return (double)(f[j]-f[k])/(y[k+1]-y[j+1]); 25 } 26 27 int main() 28 { 29 scanf("%d",&n); 30 for(int i=1;i<=n;i++) 31 scanf("%d%d",&a[i].x,&a[i].y); 32 sort(a+1,a+n+1,cmp); 33 for(int i=1;i<=n;i++) 34 { 35 while(tot&&a[i].y>=y[tot]) tot--; 36 x[++tot]=a[i].x; 37 y[tot]=a[i].y; 38 } 39 for(int i=1;i<=tot;i++) 40 { 41 while(l<r&&slope(q[l],q[l+1])<x[i]) l++; 42 int t=q[l]; 43 f[i]=f[t]+x[i]*y[t+1]; 44 while(l<r&&slope(q[r],i)<slope(q[r-1],q[r])) r--; 45 q[++r]=i; 46 } 47 printf("%lld",f[tot]); 48 return 0; 49 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步