BZOJ 1597 浅谈构造斜率--优化动态规划转移
2017-09-30 16:22
197 查看
世界真的很大
上午考试考得心累
第一题LCA写挂,第三题输出少了个感叹号???“!”
然后想下午趁头脑清晰做一道DP,然后一个班小时就这么过去了
今天运气真的是。。
复习一波斜率优化,原来学过但是感觉忘得差不多了
老老实实把方程写在纸上,一步一步写,不然真的要把自己搞蒙
看题先:
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,因为还要求分段什么的
很自然想到f[i]表示前i个土地,分成“管他多少”段并且i为最后一段末尾的最优值
那么问题就在于,土地并不是序列一样的东西,不存在”前i个土地“什么的,不能把其给出的土地顺序直接就来DP,因为这样等于分的某一段的一定是给出的顺序的连续的某一段,想想就觉得不可能
然后想一想,某一段土地的权值,是其最大的横坐标,和最大的纵坐标之积,那么在一段里面,单论横坐标应该是连续的一段,为了使得每一个x坐标覆盖的范围尽量多。
然后得出结论,这个”序列“应该和x序有一定关系,然后就把样例按x排了个序,所有矩形的左下角靠着原点
画出来,发现一个神奇的东西,”在x单调上升的同时,y单调下降“
当时就一阵蒙蔽,这难道是必然的吗
马上画了个反例。。
但是一旦出现反例,发现这个反例的矩形的x和y都被另一个更大的矩形包括,这就使得一旦选了这个更大的矩形,小矩形就完全不用考虑了,随便放进去就行
然后就把这样的矩形删掉,赫然发现:”在x单调上升的同时,y单调下降“,这就变成了一个必然的规律了
这样”序列“就出来了,我们分的所有段,必然是这些矩形里面连续的一段
然后就可以一下子写出DP方程:
f[i]=min(f[j]+a[j+1].y * a[i].x)
但是这样是n^2的,所以考虑优化
方程转移时填表法,一开始想能不能什么数据结构,但是由于右边有一个a[i].x,所以没办法用什么数据结构维护起来,因为每次选最值的条件都不一样
在这样的情况下,且与i(当前枚举项)相关的项同时出现在了方程两边,很自然,斜率优化。
设j,k,设j作为转移项比k更优,那么:
f[j]+a[j+1].y * a[i].x < f[k]+a[k+1] .y * a[i].x
然后由于i与j和k无关,所以把i挪到一边,得:
(f[j]-f[k]) / (a[k+1] .y * a[i].x - a[j+1].y * a[i].x)
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; typedef long long dnt; struct land { dnt x,y; }lnd[500010],a[500010]; int n,tot=0,q[2000010],h,t; dnt f[500010]; bool cmp(const land &a,const land &b) { if(a.x==b.x) return a.y<b.y; return a.x<b.x; } bool check_h(int i) { return f[q[h+1]]-f[q[h]] < (a[q[h]+1].y-a[q[h+1]+1].y) * a[i].x; } bool check_t(int i) { return (f[q[t]]-f[q[t-1]])*(a[q[t]+1].y-a[i+1].y) > (f[i]-f[q[t]])*(a[q[t-1]+1].y-a[q[t]+1].y); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) cin >> lnd[i].x >> lnd[i].y; sort(lnd+1,lnd+n+1,cmp); for(int i=1;i<=n;i++) { while(tot && lnd[i].y>=a[tot].y) tot--; a[++tot]=lnd[i]; } h=1,t=1,q[1]=0; for(int i=1;i<=tot;i++) { while(h<t && check_h(i)) h++; f[i]=f[q[h]]+a[q[h]+1].y*a[i].x; while(h<t && check_t(i)) t--; q[++t]=i; } cout << f[tot] << endl; return 0; } /* EL PSY CONGROO */
嗯,就是这样
相关文章推荐
- [bzoj1597][usaco2008 mar]土地购买 (动态规划+斜率优化)
- [bzoj1597][USACO2008]土地购买(DP斜率优化/四边形优化)
- 【无聊放个模板系列】BZOJ 1597 斜率优化
- BZOJ.1597.[Usaco2008 Mar]土地购买(DP 斜率优化)
- 【BZOJ1597】【Tyvj2461】土地购买,第一次的斜率优化DP
- 【BZOJ3437】小P的牧场 斜率优化 动态规划
- 【bzoj1597】土地购买 斜率优化dp
- BZOJ3156 防御准备(动态规划+斜率优化)
- 【斜率优化dp】bzoj 1597 土地购买
- 【BZOJ-1597】土地购买 DP + 斜率优化
- bzoj 1597: [Usaco2008 Mar]土地购买(斜率优化dp 例题)
- [bzoj1010](HNOI2008)玩具装箱toy(动态规划+斜率优化+单调队列)
- BZOJ 1597: [Usaco2008 Mar]土地购买【斜率优化+凸包维护】
- 【BZOJ 1597】 [Usaco2008 Mar]土地购买 (斜率优化)
- BZOJ_1096_[ZJOI2007]_仓库建设_(斜率优化动态规划+单调队列+特殊的前缀和技巧)
- [斜率DP优化]BZOJ 1597: [Usaco2008 Mar]土地购买 题解
- 斜率优化专题1——bzoj 1597 [Usaco2008 Mar] 土地购买 题解
- BZOJ 1096 [ZJOI2007]仓库建设 动态规划+斜率优化
- bzoj 1597: [Usaco2008 Mar]土地购买(斜率优化)
- BZOJ1597(Usaco2008 Mar)[土地购买]--斜率优化DP