bzoj 1597 [Usaco2008 Mar]土地购买
2016-05-21 15:43
253 查看
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
4100 1
15 15
20 5
1 100
输入解释:
共有4块土地.
Sample Output
500HINT
FJ分3组买这些土地: 第一组:100x1, 第二组1x100, 第三组20x5 和 15x15 plot. 每组的价格分别为100,100,300, 总共500.我们发现,如果有两个矩形,前一个长宽为x1 y1,后一个为x2 y2,如果x1<y1且x2<y2,则可以把前一个矩形丢掉不用。所以我们可以通过排序得到一个x递增,y递减的序列进行DP,再用斜率优化。
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; int n,tot,head,tail; long long f[50005]; int q[50005]; struct ty { long long a,b; }p[50005],t[50005]; bool cmp(ty x,ty y) { if(x.a!=y.a) return x.a<y.a; return x.b<y.b; } long long dx(int i,int j) { return t[i+1].b-t[j+1].b; } long long dy(int i,int j) { return f[j]-f[i]; } int main() { cin>>n; for(int i=1;i<=n;i++) scanf("%lld%lld",&p[i].a,&p[i].b); sort(p+1,p+n+1,cmp); for(int i=1;i<=n;i++) { while(tot>0&&p[i].b>=t[tot].b) tot--; tot++; t[tot].a=p[i].a; t[tot].b=p[i].b; } head=0;tail=0; for(int i=1;i<=tot;i++) { while(head<tail&&dy(q[head],q[head+1])<t[i].a*dx(q[head],q[head+1])) head++; int id=q[head]; f[i]=f[id]+t[i].a*t[id+1].b; while(head<tail&&dy(q[tail],i)*dx(q[tail-1],q[tail])<dy(q[tail-1],q[tail])*dx(q[tail],i)) tail--; q[++tail]=i; } cout<<f[tot]<<endl; return 0; }
相关文章推荐
- 一种利用ADC产生随机数的方法
- C++ socket函数解析
- 如何从Hadoop官网下载hadoop开发包
- iOS开发实战:使用Swift语言自定义Pull To Refresh控件
- xin10下Genymotion无法拖拽的问题
- UVA 536 Tree Recovery (二叉树重建)
- IOS使用NSURLRequest或NSURLSession获取沙河目录下文件数据
- Google工程师带你一起看2016 Google IO最酷的8项发布
- CSS float浮动的深入研究、详解及拓展 一 一 一 一 一 一 一 一
- linux小记:makefile(随使用程度持续更新)
- Quartz2D 编程指南(三)渐变、透明层 、数据管理
- C++ 虚函数表解析
- CentOS7 安装与配置Ant
- PE文件学习
- Linux下配置rsync 同步数据
- Java字节码简介
- 使用JMeter的自定义脚本进行性能测试
- 利用Cisco Packet Tracer仿真配置网络
- 文章标题
- 简单掌握JavaScript中const声明常量与变量的用法