bzoj1597 土地购买
2016-01-19 19:55
309 查看
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
* 第一行: 最小的可行费用.dp斜率优化
对土地(x1,y1)和(x2,y2),若x1≥x2且y1≥y2,则可忽略(x2,y2)
将土地按x升序y降序排序,忽略不必考虑的土地
f[i]=max{f[j]+x[i]*y[j+1]}(0<j<i)
若k优于j则f[j]-f[k]>x[i]*(y[k+1]-y[j+1])
#include<cstdio> #include<algorithm> struct pos{ long long x,y; }vs[50001],ps[50001]; int pp=1; bool operator<(pos a,pos b){ if(a.x==b.x)return a.y<b.y; return a.x<b.x; } long long f[50001]; int q[50001]={0}; int qs=0,qe=0; int n; inline long long A(int x,int y){ return f[x]-f[y]; } inline long long B(int x,int y){ return ps[y+1].y-ps[x+1].y; } int main(){ scanf("%d",&n); for(int i=0;i<n;i++)scanf("%d%d",&vs[i].x,&vs[i].y); std::sort(vs,vs+n); for(int i=0;i<n;i++){ while(pp>1&&ps[pp-1].y<=vs[i].y)--pp; ps[pp++]=vs[i]; } for(int i=1;i<pp;i++){ while(qs<qe&&A(q[qs],q[qs+1])>ps[i].x*B(q[qs],q[qs+1]))++qs; int w=q[qs]; f[i]=f[w]+ps[i].x*ps[w+1].y; while(qs<qe&&A(q[qe-1],q[qe])*B(q[qe],i)>=A(q[qe],i)*B(q[qe-1],q[qe]))--qe; q[++qe]=i; } printf("%lld",f[pp-1]); return 0; }
相关文章推荐
- java.lang.ClassNotFoundException与java.lang.NoClassDefFoundError的区别
- div+css截取字符串在规定长度,超出部分用。。。代替
- 关于内存单元的一点点
- 再好的香水也斗不过韭菜合子
- uva 846 - Steps
- SQL UNION 和 UNION ALL 操作符
- Androidx学习笔记(5)--短信发送器
- 批量删除.svn文件夹和.svn文件
- UBUNTU的默认root密码 && VirtualBox内Linux系统怎样与Windows共享文件夹
- ZOJ1003
- Vertica数据库操作
- 批量删除.svn文件夹和.svn文件
- 组合数打表
- 网络编程-TCP程序实例(client端heserver端相互通信)
- java 读取properties配置文件
- leetcode之 Maximum Depth of Binary Tree
- ProgressDialog的hide()和dismiss()方法
- Java NIO Pipe
- 快速排序
- Android加壳native实现