usaco 土地并购 && hdu 玩具装箱
土地并购:
Description
约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地。如果约翰单买一块土地,价格就是土地的面积。但他可以选择并购一组土地,并购的价格为这些土地中最大的长乘以最大的宽。比如约翰并购一块3 × 5和一块5 × 3的土地,他只需要支付5 × 5 = 25元,比单买合算。
约翰希望买下所有的土地。他发现,将这些土地分成不同的小组来并购可以节省经费。给定每份土地的尺寸,请你帮助他计算购买所有土地所需的最小费用。
Input Format
第一行:一个整数:N,1 ≤ N ≤ 50000
第二行到第M + 1行:第i + 1行有两个整数,分别代表第i块土地的长度Hi和宽度Wi,1 ≤ Hi,Wi ≤ 106
Output Format
第一行:购买所有土地所需的最小费用
----------------------------------------------------------------
预处理:
将 x 从小到大排序
显然对于 xj < xi 且 yj<xi 时,这个 j 就是无用
将这样的点删除后,x 递增 ,y递减
考虑DP方程:
状态 :f[i] 买前 i 个土地的最少价值。
转移 :f[i] = min( f[j-1] + x[i] * y[j] ) (1<= j <= i )
考虑优化:
设存在决策 j ,k 当 j 决策优于 k 决策时
也就是 : f[j-1] + x[i] * y[j] < f[k-1]+x[i] * y[k]
进行一个简单的变化 :
f[j-1] - f[k-1] < x[i] * (y[k] - y[j] )
假设 y[k] - y[j] > 0 ,也就是 k < j
(f[j-1] - f[k-1]) / (y[k] - y[j]) < x[i]
设点 J ( -y[j] , f[j-1] ) , K(-y[k] , f[k-1])
也就是 对于横坐标 J > K 时,如果JK连线的斜率小于 x[i] 时 j 决策优于 k 决策
对于 J 仅保留在 J 前与 J 构成斜率最大的点即可,
在维护上述条件时,如果存在 i < j < k 且 斜率 Kij > Kjk 则 j 就不可能是最优决策
证明 :在 j 成为当前决策时 , k 显然会比 j 决策优 !
Ps.其实就是维护一个下凸壳- =
有了上述这个性质,通过二分求答案即可 O( n logn );
又注意到 x 是 递增的 ,所以可以增加一个弹队头的操作(感谢Lazycal大神指导)
Dp复杂度为O( n )!
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<iostream>
#define INF 999999999999
#define LL long long
#define N 1000010
//using namespace std ;
struct P{
LL x,y;
P(const LL b=,const LL c=) : x(b),y(c){}
}map[N],q[N];
bool cmp(const P &a,const P &b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int top,head,n,next[N];
LL f[N];
inline LL cross(P a, P b,P c){
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
void addpoint(P now){
while(top->&&cross(q[top-],q[top],now)<=) --top;
q[++top]=now;
}
int main(){
freopen("xx.in","r",stdin);
freopen("xx.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%I64d%I64d",&map[i].x,&map[i].y);
std :: sort(map+,map++n,cmp);
int last=n;
for(int i=n-;i;i--){
if(map[i].y<=map[last].y) continue ;
next[i]=last;
last=i;
}
int b;
for(int i=;i<=n;i++)
if(next[i]){
b=i;
break;
}
head=;
for(int last=,i=b; i ;last=i,i=next[i]){
addpoint(P(-map[i].y,f[last]));
// 二分做法 -->
/*int l=1,r=top,temp=0;
while(l<=r){
int mid=(l+r)>>1;
if(mid==1||q[mid].y-q[mid-1].y<=map[i].x*(q[mid].x-q[mid-1].x)){
temp=mid;
l=mid+1;
} else r=mid-1;
}
f[i]=q[temp].y+map[i].x*(-q[temp].x);*/
// 最优解->
while(head<top&&q[head+].y-q[head].y<=map[i].x*(q[head+].x-q[head].x)) ++head;
f[i]=q[head].y+map[i].x*(-q[head].x);
}
printf("%I64d",f[n]);
}
-------------------------------------------------------------------------
玩具装箱:
Description
P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中。P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的。同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为x,其制作费用为(X-L)^2.其中L是一个常量。P教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过L。但他希望费用最小.
Input
第一行输入两个整数N,L.接下来N行输入Ci.1<=N<=50000,1<=L,Ci<=10^7
Output
输出最小费用
---------------------------------------------------------------------------
和上题基本一样,也是斜率优化
预处理 g[i]=∑(ci+1)
Dp方程: f[i]=f[j]+(g[i]-g[j]-1-L)^2
设 g[i]-1-L 为 常数 K
简单的展开可得:
f[i]=K^2+f[j]+sum[j]^2-2*K*sum[j]
当 j 优于 k 时
K^2+f[j]+sum[j]^2-2*K*sum[j]<K^2+f[k]+sum[k]^2-2*K*sum[k]
设 y[a]=f[a]+sum[a]^2 , x[a]=sum[j] 化简可得 :
y[j]-y[k]<2*k(x[j]-x[k])
假设 j>k 则 x[j]>x[k]
当 y[j]-y[k]/x[j]-x[k]< 2*k 时 j 优于 k
然后就真的和上题一样了 - =
Ps. 感谢大胖, 小胖 , lazycal等大神指导
代码如下:
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<iostream>
#include<queue>
#define INF 99999999
#define LL long long
#define N 100010
//using namespace std;
LL L,tail,head,n,g[N],f[N];
struct P{
LL x,y;
P (const LL X=,const LL Y=): x(X),y(Y){}
}q[N];
inline LL cross(P a,P b,P c){
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
void addpoint(P now){
while(tail>&&cross(q[tail-],q[tail],now)<=) --tail;
head=std::min(head,tail);
q[++tail]=now;
}
int main(){
scanf("%lld%lld",&n,&L);
for(LL l,i=;i<=n;i++){
scanf("%lld",&l);
g[i]=g[i-]+l+;
}
head=;
tail=;
for(LL k,i=;i<=n;i++){
addpoint(P(g[i-],f[i-]+g[i-]*g[i-]));
k=g[i]--L;
while(head<tail&&q[head+].y-q[head].y<=*k*(q[head+].x-q[head].x)) ++head;
f[i]=q[head].y-*k*q[head].x+k*k;
}
printf("%lld",f[n]);
}
usaco 土地并购 && hdu 玩具装箱的更多相关文章
- 玩具装箱&土地购买
今天一天8h 写了两道斜率优化的题(别问我效率为什么这么低 代码bug太多了) 关键是思考的不周全 估计是写的题少手生 以后就会熟练起来了吧. 这道题显然有一个n^2的dp方程 设f[i]表示前i件物 ...
- bzoj1010 玩具装箱
玩具装箱 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
- BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9812 Solved: 3978[Submit][St ...
- 【BZOJ-1010】玩具装箱toy DP + 斜率优化
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8432 Solved: 3338[Submit][St ...
- C++之路进阶——codevs1319(玩具装箱)
1319 玩具装箱 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description P教授要去看奥运,但是他舍不下他的玩具,于是 ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- 【BZOJ】【1010】【HNOI2008】玩具装箱Toy
DP/斜率优化 根据题目描述很容易列出动规方程:$$ f[i]=min\{ f[j]+(s[i]-s[j]+i-j-1-L)^2 \}$$ 其中 $$s[i]=\sum_{k=1}^{i} c[k] ...
- 【bzoj1010】[HNOI2008]玩具装箱toy
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9281 Solved: 3719[Submit][St ...
- 【斜率DP】BZOJ 1010:玩具装箱
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7537 Solved: 2888[Submit][St ...
随机推荐
- 一个开源的可视化的jQuery工作流插件
特点 1.跨浏览器,可兼容IE7--IE11, FireFox, Chrome, Opera等几大内核的浏览器,且不需要浏览器再加装任何控件. (IE7-IE8时,使用VML:IE9以上,FF,OPE ...
- NetSerialComm的基本使用方法
近期搞一个com口传输的小项目,原来认为是一个挺简单的一个小功能,结果生产商发来com以后直接傻眼了,还要对相关的硬件流进行处理 如下 // 硬件流控制设置 dcb.fOutxCtsFlow = FA ...
- PHP - PHPExcel操作xls文件
读取中文的xls.csv文件会有问题,网上找了下资料,发现PHPExcel类库好用,官网地址:http://phpexcel.codeplex.com/ 1.读取xls文件内容 <?php // ...
- var t = a&&b;的问题
var a = "avalue";var b = "bvalue";var t = a&&b;console.info(t); // bvalu ...
- Python正则表达式学习
1.Python的正则表达式需要用到re模块,有两个方法:match和search,match从第一个字符串开始匹配,search从任意字符串开始匹配,所以match比search严格. 如果匹配成功 ...
- C#中多线程写DataGridView出现滚动条导致程序卡死(无响应)的解决办法
因为写的程序涉及到多线程维护一个DataGridView,然后蛋疼的发现经常卡死...一开始以为是读写冲突的原因,然后就加了锁,问题依旧...然后发现每次出现滚动条的时候程序才会无响应,所以感觉应该是 ...
- 【转】【Top 100 Best Blogs for iOS Developers】
原文地址:http://www.softwarehow.com/best-blogs-for-ios-developers/ (by JP Zhang | Last updated: Apr 5, 2 ...
- 加密你的SQLite
转自王中周的个人博客 关于SQLite SQLite是一个轻量的.跨平台的.开源的数据库引擎,它的在读写效率.消耗总量.延迟时间和整体简单性上具有的优越性,使其成为移动平台数据库的最佳解决方案(如iO ...
- JavaScript 语言基础知识点总结
网上找到的一份JavaScript 语言基础知识点总结,还不错,挺全面的. (来自:http://t.cn/zjbXMmi @刘巍峰 分享 )
- Linux技术修复
今天在慕课网上学习了Linux的一些知识: 我使用命令: ***:~$ route add default gw 192.168.1.1 添加了一个网关:192.168.1.1之后的结果为: ***: ...