[BZOJ1597][Usaco2008 Mar]土地购买(斜率优化dp)
2016-04-25 18:28
495 查看
题目描述
传送门题解
显然如果土地A的长宽都小于土地B,那么土地A是没有价值的,顺带买了就行了。那么首先把长和宽都被其它土地包括的土地都去掉。之后我们可以得到一个长升序宽降序的序列,那么令f[i]表示买前i块土地的最小费用,得到转移方程:f[i]=min{f[j]+p[i]*q[j+1]} i>j 其中p和q分别为长和宽,显然可以用斜率优化。
代码
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define LL long long const int max_n=5e4+5; int n,head,tail,cnt,p[max_n],q[max_n],queue[max_n]; struct hp{int x,y;}squ[max_n]; LL f[max_n]; inline int cmp(hp a,hp b){return a.x<b.x||a.x==b.x&&a.y<b.y;} inline LL K(int j){return q[j+1];} inline LL B(int j){return f[j];} inline LL Y(int i,int j){return K(j)*p[i]+B(j);} inline bool cmp1(int x1,int x2,int x3){ LL w1=(K(x1)-K(x3))*(B(x2)-B(x1)); LL w2=(K(x1)-K(x2))*(B(x3)-B(x1)); return w1>=w2; } int main(){ scanf("%d",&n); for (int i=1;i<=n;++i) scanf("%d%d",&squ[i].x,&squ[i].y); sort(squ+1,squ+n+1,cmp); for (int i=1;i<=n;++i){ while (cnt&&squ[i].y>=q[cnt]) cnt--; p[++cnt]=squ[i].x,q[cnt]=squ[i].y; } head=tail=0; for (int i=1;i<=n;++i){ while (head<tail&&Y(i,queue[head+1])<=Y(i,queue[head])) head++; f[i]=Y(i,queue[head]); while (head<tail&&cmp1(i,queue[tail-1],queue[tail])) tail--; queue[++tail]=i; } printf("%lld\n",f[cnt]); }
相关文章推荐
- mysql相似于oracle的to_char() to_date()方法
- 模拟大数据的基本计算, 以解决常规计算器计算数据时位数的有限性
- UVA10723 Cyborg genes (LCS)
- UVa 101 - The Blocks Problem
- java显示声音波形图示例
- 123
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 链表中环的入口结点
- linux jps: command not found
- [设计模式学以致用]备忘录模式
- Qt文件读写操作
- strtok() 用于分割字符串
- 使用IPtables 实现数据转发
- php安装
- 简单的cc攻击防御
- 【MongoDB】常用知识点
- python自底向上的执行单元测试
- Fragment 内实现对返回键的监听处理
- System and Device Programming------Kernel
- 操作系统笔试面试笔记总结