1597: [Usaco2008 Mar]土地购买

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 5115  Solved: 1897
[Submit][Status][Discuss]

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

4
100 1
15 15
20 5
1 100

输入解释:

共有4块土地.

Sample Output

500

HINT

FJ分3组买这些土地: 第一组:100x1, 第二组1x100, 第三组20x5 和 15x15 plot. 每组的价格分别为100,100,300, 总共500.


首先对决策的有序,对土地按照长 x,宽 y 递增排序。

如果:

第一块土地,和第二块土地,第二块土地长宽都要比第一块大,那么第一块就等于不起作用,那么可以不用考虑第一块土地,

于是删掉所有这种不需要考虑的土地,就成了 x 递增,y 递减排列的土地。

这时候,对于前面 i 块土地来说,会可以分成很多部分,要成本最少的一种划分。于是——DP思路就来了。

f[i] 前 i 块土地的最优值。

那么:

这样O(n^2) 的算法就呼之欲出了,但是,还是会TLE;

怎么办呢?


斜率DP:

对于 i 点,与之相切的点 斜率才最小,保证 < x[i] ,这个点才是划分点。

到这里,分析就已经完成了,只差队列维护决策点。这个凸多边形了。

就是套路了,

  • 考虑凸多边相切的变化规律,找到划分点。
  • 用划分点计算新的值。
  • 新的值更新凸多边形
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = ; struct Node
{
ll x,y;
bool operator < (const Node& rhs) const {
if(x==rhs.x) return y < rhs.y;
return x < rhs.x;
}
}p[maxn]; ll n,f[maxn],q[maxn]; double slope(long long a,long long b) {
return (1.0*(f[a]-f[b])/(p[a+].y-p[b+].y));
} int main(int argc, char const *argv[])
{
scanf("%I64d",&n); for(int i = ; i <= n; i++)
scanf("%I64d%I64d",&p[i].x,&p[i].y); sort(p+,p+n+); int cnt = ;
for(int i = ; i <= n; i++) {
if(p[i].y<=p[i+].y) continue;
while(cnt&&p[cnt].y<=p[i].y) --cnt;
p[++cnt] = p[i];
} int h = ,t = ;
q[h] = ; for(int i = ; i <=cnt; i++) {
while(t-h>&&slope(q[h],q[h+])>=-p[i].x) ++h; //删除队首非最优决策点 f[i] = f[q[h]] + p[q[h]+].y * p[i].x; while(t-h>&&slope(q[t-],q[t-])<slope(q[t-],i)) --t;
q[t++] = i; } cout<<f[cnt]<<endl;
return ;
}

参考:http://www.cnblogs.com/akhpl/p/6715148.html

bzoj 1597 斜率DP的更多相关文章

  1. 【无聊放个模板系列】BZOJ 1597 斜率优化

    STL 双向队列DEQUE版本 #include<cstdio> #include<cstdlib> #include<cstring> #include<i ...

  2. 【BZOJ 1597】 [Usaco2008 Mar]土地购买 (斜率优化)

    1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3601  Solved: 1322 Descrip ...

  3. bzoj 3437 斜率优化DP

    写题解之前首先要感谢妹子. 比较容易的斜率DP,设sum[i]=Σb[j],sum_[i]=Σb[j]*j,w[i]为第i个建立,前i个的代价. 那么就可以转移了. /**************** ...

  4. bzoj 3156 防御准备(斜率DP)

    3156: 防御准备 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 837  Solved: 395[Submit][Status][Discuss] ...

  5. bzoj 1010 斜率优化DP

    我的第二道斜率DP. 收获: 1.假设两个位置:p<q<i,然后让某一位置优,看其满足什么性质,所谓斜率优化就是满足: (g[q]-g[p])/(f[q]-f[p])  op h[i] 要 ...

  6. bzoj4518: [Sdoi2016]征途--斜率DP

    题目大意:把一个数列分成m段,计算每段的和sum,求所有的sum的方差,使其最小. 由方差*m可以化简得ans=m*sigma(ki^2)-sum[n]^2 很容易得出f[i][j]=min{f[i- ...

  7. hdu 3507 斜率dp

    不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个 ...

  8. 斜率dp cdq 分治

    f[i] = min { f[j] + sqr(a[i] - a[j]) } f[i]= min { -2 * a[i] * a[j] + a[j] * a[j] + f[j] } + a[i] * ...

  9. HDU 2829 Lawrence (斜率DP)

    斜率DP 设dp[i][j]表示前i点,炸掉j条边的最小值.j<i dp[i][j]=min{dp[k][j-1]+cost[k+1][i]} 又由得出cost[1][i]=cost[1][k] ...

随机推荐

  1. js栈内存和堆内存的区别

    首先JavaScript中的变量分为基本类型和引用类型.基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象. 1.基本类型 基本类型有Undefined.Null.Boo ...

  2. Java基础26-对象初始化过程

    /* 1.因为new Test1()用到了Test1类,所以会把它从硬盘上加载进入内存 2.如果有static静态代码块就会随着类的加载而执行,还有静态成员和普通方法也会随着类的加载而被加载 3.在堆 ...

  3. zookeeper简单命令

    bin/zkCli.sh -server ls / create /zk_test my_data get /zk_test set /zk_test admln delete /zk_test ad ...

  4. 18 Command Line Tools to Monitor Linux Performance

    By Ravi Saive Under: Linux Commands, Monitoring Tools On: December 26, 2013 http://www.tecmint.com/c ...

  5. 对key中有数字的字典进行排序

    word_cloud = []cc = [{"c58":341,"c59":525,"c56":507,"c57":34 ...

  6. C#事件(event)解析委托

    namespace Vczx.ProCSharp.Event { /// <summary> /// 类EatEventArgs 必须继承自类EventArgs,用来引发事件时封装数据 / ...

  7. LINQ和.NET数据访问

    .NET数据访问 在.NET中对于数据的访问大致有三个层面,数据访问层.内存数据集.业务逻辑层.数据层,包括了XML配置文件以及一些常用的数据库(使用SQL语句):内存数据集,主要是DataSet数据 ...

  8. 关于IQueryable和IEnumerable

    园里对这两个已经有很多文章作了深入的介绍,我总结些,当成笔记用. 一.具体判断用哪个上,如果是运行在本地内存中的,用IEnumerable,枚举该对象时,会立即反应查询结果. 如果是远程数据源,比如数 ...

  9. 折半查找——Java实现

    一.查找思想 折半查找 也称为二分查找,是一种效率较高的查找方法,查找时要求表中的节点按关键字的大小排序,并且要求线性表顺序存储. 首先用要查找的关键字值(key)与中间位置结点的关键字值(arr[m ...

  10. C#学习笔记9

    1.多播委托:由与delegate关键字声明的委托,在编译后默认继承Delegate与MulticastDelegate类型,所以声明的委托自然就含有多播委托的特性,即一个委托变量可以调用一个方法链( ...