转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24387147

【原题】

1597: [Usaco2008 Mar]土地购买

Time Limit: 10 Sec  Memory Limit: 162 MB

Submit: 1396  Solved: 480

[Submit][Status]

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.

Source

【分析】太神了!看了JokerPark大牛的博客,受益匪浅。可是有些地方開始还是没看懂,因此自己也推了半天公式。

设第i块地的长和宽是ai,bi。

①先考虑无效的边。设ai>=aj且bi>=bj,那么j一定是无效边。怎么求呢?首先我们把ai按升序排序,然后做一遍类似于单调队列的操作。枚举i,假设bi>=队列尾部的bj,那么尾指针就减1。由于a已经是升序排好了,ai>=aj是肯定的。

②去掉边后,我们还发现了一个有趣的性质。在队列中,由于a一定是升序排好的,那么b一定是降序的。(自己YY)

③于是DP方程呼之欲出:f[i]=max(f[i],f[j]+a[j+1]*b[i])。毫无疑问,这是一个超时的算法。如今就要推斜率优化了!!设在当前的状态f[i]时,从f[j]转移比f[k]优。那么f[j]+a[j+1]*b[i]<f[k]+a[k+1]*b[i]。化简一下:b[i]<(f[k]-f[j])/(a[j+1]-a[k+1])。说明,假设j和k满足上述要求,k能够无视了,由于j一定比k更优。依据这个,我们维护一个单调队列。

【代码】

#include<cstdio>
#include<algorithm>
#define N 50005
using namespace std;
struct arr{long long x,y;}a[N],b[N];
long long f[N],q[N],n,i,h,t,m;
bool cmp(arr a,arr b){return a.x<b.x||a.x==b.x&&a.y>b.y;}
int main()
{
scanf("%lld",&n);
for (i=1;i<=n;i++)
scanf("%lld%lld",&b[i].x,&b[i].y);
sort(b+1,b+n+1,cmp);
m=1;a[1].x=b[1].x;a[1].y=b[1].y;
for (i=2;i<=n;i++)
{
while (m&&b[i].y>a[m].y) m--;
a[++m].x=b[i].x;a[m].y=b[i].y;
}
h=1;t=1;q[1]=0;f[0]=0;
for (i=1;i<=m;i++)
{
while ((h<t)&&(a[i].x*(a[q[h]+1].y-a[q[h+1]+1].y)>f[q[h+1]]-f[q[h]])) h++;
f[i]=f[q[h]]+a[q[h]+1].y*a[i].x;
while ((h<t)&&(f[i]-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[i+1].y)) t--;
q[++t]=i;
}
printf("%lld",f[m]);
return 0;
}

斜率优化专题1——bzoj 1597 [Usaco2008 Mar] 土地购买 题解的更多相关文章

  1. BZOJ 1597: [Usaco2008 Mar]土地购买 [斜率优化DP]

    1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4026  Solved: 1473[Submit] ...

  2. BZOJ 1597: [Usaco2008 Mar]土地购买( dp + 斜率优化 )

    既然每块都要买, 那么一块土地被另一块包含就可以不考虑. 先按长排序, 去掉不考虑的土地, 剩下的土地长x递增, 宽y递减 dp(v) = min{ dp(p)+xv*yp+1 } 假设dp(v)由i ...

  3. BZOJ 1597: [Usaco2008 Mar]土地购买【斜率优化+凸包维护】

    1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4989  Solved: 1847[Submit] ...

  4. BZOJ 1597: [Usaco2008 Mar]土地购买 斜率优化

    1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec  Memory Limit: 162 MB Description 农夫John准备扩大他的农场,他正在考虑N ...

  5. bzoj 1597 [Usaco2008 Mar]土地购买——斜率优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1597 又一道斜率优化dp.负数让我混乱.不过仔细想想还是好的. 还可以方便地把那个负号放到x ...

  6. BZOJ 1597 [Usaco2008 Mar]土地购买:斜率优化dp

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1597 题意: 有n块矩形土地,长为a[i],宽为b[i]. FJ想要将这n块土地全部买下来 ...

  7. bzoj 1597: [Usaco2008 Mar]土地购买【斜率优化】

    按xy降序排序,把能被完全包含的去掉 然后就得到了x升序y降序的一个数组 然后方程就显然了:f[i]=min(f[j]+y[j+1]x[i]) 斜率优化转移 说起来我还不会斜率优化呢是不是该学一下了 ...

  8. BZOJ 1597: [Usaco2008 Mar]土地购买 动态规划 + 斜率优化

    Code: #include<bits/stdc++.h> #define maxn 1000000 #define ll long long #define x(i) (b[i+1]) ...

  9. bzoj 1597: [Usaco2008 Mar]土地购买

    Description 农 夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <= 1,000 ...

随机推荐

  1. 引用类型 (Reference Type Matters)、扩展与派发方式

    引用类型 (Reference Type Matters) 引用的类型决定了派发的方式. 这很显而易见, 但也是决定性的差异. 一个比较常见的疑惑, 发生在一个协议拓展和类型拓展同时实现了同一个函数的 ...

  2. eureka 注册中心

    1.eureka版本更新后,pom依赖名称变化 v1.2.7spring-cloud-starter-eureka-server v2.0.0spring-cloud-starter-netflix- ...

  3. CAD使用SetxDataLong写数据(com接口)

    主要用到函数说明: MxDrawEntity::SetxDataLong 写一个long扩展数据,详细说明如下: 参数 说明 [in] BSTR val 字符串值 szAppName 扩展数据名称 n ...

  4. Java基础(十四)--装箱、拆箱详解

    Java中基本数据类型都有相对应的包装类 什么是装箱?什么是拆箱? 在Java SE5之前,Integer是这样初始化的 Integer i = new Integer(10); 而在从Java SE ...

  5. 【计算机网络】2.5 DNS:因特网的目录服务

    第二章第五节 因特网的目录服务 DNS(域名系统)提供了一种能运行主机名到IP地址转换的因特网目录服务:一方面,他让人能够记住如taobao.com这样的主机别名:另一方面,他提供给路由器可理解的IP ...

  6. B1. Concurrent 多线程的创建

    [概述] 多线程的创建常用的有两种方法:1). 继承 Thread 类: 2). 实现 Runnable 接口: 3). 实现 Callable 接口. [继承 Thread 类] /** * 1. ...

  7. 亲测可用)html5 file调用手机摄像头

    在切图网一个客户的webapp项目中需要用到 html5调用手机摄像头,找了很多资料,大都是 js调用api  然后怎样怎样,做了几个demo测试发现根本不行, 后来恍然大悟,用html5自带的 in ...

  8. C++11新特性之final override标识符

    final: final修饰符可用于修饰类,放在类名后面,被final修饰符修饰的类不能被继承.示例代码: // 正确的示范 #include <iostream> class A { p ...

  9. C++ STL容器之 stack

    STL 中的 stack 是一种容器适配器,而不是一种容器. 它是容器适配器是指,只要支持一系列方法的容器(empty, size, back, push_back, pop_back),都能作为st ...

  10. VIM命令大全(图+文)

    在命令状态下对当前行用== (连按=两次), 或对多行用n==(n是自然数)表示自动缩进从当前行起的下面n行.你可以试试把代码缩进任意打乱再用n==排版,相当于一般IDE里的code format.使 ...