转载请注明: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. HDU_3792_(素数筛+树状数组)

    Twin Prime Conjecture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  2. 使用JDBC创建出版社和书籍管理系统

    1.需求 已知如下两个表: publisher id name(唯一) address book id isbn name publisher_id 欢迎进入书籍管理系统 1.出版社管理:增.删(na ...

  3. Centos7 安装MongoDB的详细过程

    一.简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品 ...

  4. django 标签

    django标签 {% if/for/ifequal/ifnotequal condition %} ...{{ name|first|lower}}{# interpretation:lower t ...

  5. Swing实现个人简历

    源码: import java.awt.Container;import java.awt.FlowLayout;import java.awt.Font; import javax.swing.*; ...

  6. [C#] 对List进行分组排序后输出

    Student 类: public class Student { public int ID { get; set; } public string Name { get; set; } publi ...

  7. Chrome插件:本地程序实现验证码破解(浏览器与本地进程通信)

    利用chrome调用本地程序破解图片验证码background.js var port = null, tabId, fname = "vcode.chrome.v1.item.01&quo ...

  8. C++如何显式调用常成员函数

    C++的常成员函数与同名成员函数重载时,该如何显式调用常成员函数? 具体的一个小例子: #include <iostream> using namespace std; class C1 ...

  9. eclipse 导入svn项目并添加server

    1.打开svn资源库 window-->show view-->other-->svn-->svn资源库 2.控制台选中文件夹右键-->检出为--finish 3.添加服 ...

  10. ruby on rails安装(win7x64)

    Ruby下载地址http://rubyinstaller.org/downloads/ (以安装2.1.7为例,2.2.3未能安装成功) 安装完之后测试是否安装成功