bzoj 1597: [Usaco2008 Mar]土地购买
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
100 1
15 15
20 5
1 100
输入解释:
共有4块土地.
Sample Output
HINT
FJ分3组买这些土地: 第一组:100x1, 第二组1x100, 第三组20x5 和 15x15 plot. 每组的价格分别为100,100,300, 总共500.
Source
首先这个题仍然是一个划分性DP。。。
所以设的状态仍然和之前的划分性DP相同。。。
首先考虑最裸的暴力。。。
f[i]=min(f[j]+max(q[j+1到i].b)*max(q[j+1到i].a));
然后我们发现一个很严肃的问题。。。
这个方程在转移的时候有max那么显然是不会满足决策单调性的。。。
这个暴力可以通过ST表预处理实现n^2。然而这个复杂度是明显不行的。。。
我们要做的就是尽量的去掉这些max。。。去掉max的方法就是使这些权值都是单调的,那么我们直接查询端点即可,就不需要max了。。
首先考虑让a单调,这样通过一遍sort即可以做到。。。
然后方程变为了:
f[i]=min(f[j]+max(q[j+1到i].b)*q[i].a);
然而还是有一个max的仍然没有单调性,复杂度仍然是n^2;
那么我们如何再把b变成单调的呢???因为只有这样才能去掉max。。
如果把土地尺寸用二维坐标表示时:

显然如果通过把a排序之后,图中两个红点是不会产生任何贡献的。。。
所以对于一个点在把a排了序之后,对于一个点如果后面还有b值大于他的b值时,这个点可以被覆盖掉(他不会有任何贡献)。。。
这个其实可以线性扫,然而我暴力打了ST表懒得删了
然后把这些点删掉之后,a权值是单调递增的,b权值是单调递减的。。。
方程被化为:
f[i]=min(f[j]+q[j+1].b*q[i].a);
这个式子就是一个经典的决策单调性式子了。。。
满足决策单调性,可以用二分栈完美解决了。。。nlogn
附上代码
// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#include<set>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#define int long long
#define lson num<<1
#define rson num<<1|1
using namespace std;
typedef long long ll;
const int N=100050;
int gi()
{
int x=0,flag=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*flag;
}
struct ac{int a,b;}qq[N],nw[N];
struct data{int l,r,p;}q[N];
int n,f[N],pre[20],pre2[N],ST[N][20];
bool cmp(ac a,ac b){
return a.a<b.a;
}
int cal(int j,int i){
return f[j]+nw[j+1].b*nw[i].a;
}
void makeST()
{
pre[0]=1;for(int i=1;i<=18;i++) pre[i]=pre[i-1]<<1;
pre2[0]=-1;for(int i=1;i<=n;i++) pre2[i]=pre2[i>>1]+1;
for(int i=1;i<=n;i++) ST[i][0]=qq[i].b;
for(int j=1;j<=18;j++)
for(int i=1;i<=n;i++){
if(i+pre[j]-1<=n){
int x1=ST[i][j-1],x2=ST[i+pre[j-1]][j-1];
ST[i][j]=max(x1,x2);
}
}
}
int query(int l,int r)
{
if(l==r)return qq[l].b;
int x=pre2[r-l+1];
int x1=ST[l][x],x2=ST[r-pre[x]+1][x];
int ans=max(x1,x2);
return ans;
}
int find(data t,int x){
int l=t.l,r=t.r;
while(l<=r){
int mid=(l+r)>>1;
if(cal(t.p,mid)<cal(x,mid))
l=mid+1;
else r=mid-1;
}
return l;
}
main()
{
n=gi();
for(int i=1;i<=n;i++) qq[i].a=gi(),qq[i].b=gi();
sort(qq+1,qq+1+n,cmp);
makeST();
int tot=0;
for(int i=1;i<=n;i++){
if(qq[i].b>=query(i+1,n)){
nw[++tot]=qq[i];
}
}
int head=1,tail=0;
q[++tail]=(data){0,tot,0};
for(int i=1;i<=tot;i++){
while(head<=tail&&i>q[head].r) head++;
f[i]=cal(q[head].p,i);
if(head>tail||cal(i,tot)<=cal(q[tail].p,tot)){
while(head<=tail&&cal(i,q[tail].l)<=cal(q[tail].p,q[tail].l))
tail--;
if(head>tail)
q[++tail]=(data){i,tot,i};
else{
int t=find(q[tail],i);
q[tail].r=t-1;
q[++tail]=(data){t,tot,i};
}
}
}
printf("%lld",f[tot]);
}
bzoj 1597: [Usaco2008 Mar]土地购买的更多相关文章
- BZOJ 1597: [Usaco2008 Mar]土地购买 [斜率优化DP]
1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4026 Solved: 1473[Submit] ...
- BZOJ 1597: [Usaco2008 Mar]土地购买( dp + 斜率优化 )
既然每块都要买, 那么一块土地被另一块包含就可以不考虑. 先按长排序, 去掉不考虑的土地, 剩下的土地长x递增, 宽y递减 dp(v) = min{ dp(p)+xv*yp+1 } 假设dp(v)由i ...
- BZOJ 1597: [Usaco2008 Mar]土地购买【斜率优化+凸包维护】
1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4989 Solved: 1847[Submit] ...
- BZOJ 1597: [Usaco2008 Mar]土地购买 斜率优化
1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec Memory Limit: 162 MB Description 农夫John准备扩大他的农场,他正在考虑N ...
- 斜率优化专题1——bzoj 1597 [Usaco2008 Mar] 土地购买 题解
转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24387147 [原题] 1597: [Usaco2008 Mar]土地购买 Time ...
- BZOJ 1597 [Usaco2008 Mar]土地购买:斜率优化dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1597 题意: 有n块矩形土地,长为a[i],宽为b[i]. FJ想要将这n块土地全部买下来 ...
- bzoj 1597 [Usaco2008 Mar]土地购买——斜率优化dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1597 又一道斜率优化dp.负数让我混乱.不过仔细想想还是好的. 还可以方便地把那个负号放到x ...
- bzoj 1597: [Usaco2008 Mar]土地购买【斜率优化】
按xy降序排序,把能被完全包含的去掉 然后就得到了x升序y降序的一个数组 然后方程就显然了:f[i]=min(f[j]+y[j+1]x[i]) 斜率优化转移 说起来我还不会斜率优化呢是不是该学一下了 ...
- BZOJ 1597: [Usaco2008 Mar]土地购买 动态规划 + 斜率优化
Code: #include<bits/stdc++.h> #define maxn 1000000 #define ll long long #define x(i) (b[i+1]) ...
随机推荐
- 计算出前N项的数据
#include<iostream> #include<algorithm> #include<numeric> using namespace std; ; in ...
- 40.Linux应用调试-使用gdb和gdbserver
1.gdb和gdbserver调试原理 通过linux虚拟机里的gdb,来向开发板里的gdbserver发送命令,比如设置断点,运行setp等,然后开发板上的gdbserver收到命令后,便会执行应用 ...
- gulp入门详细教程
简介:gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成:使用她,我们不仅可以很愉快的编写代码, ...
- Python的变量及简单数据类型
Python的变量及简单类型 1. 变量 在Python编程中,变量是用来存放值或对像的容器.变量的名称可以自定义,但需遵循一定的规范,否则可能会引发一些错误.Python的变量可以分为数字.字符和 ...
- java环境变量配置原理解析以及eclipse导入外包的方法
1. PATH环境变量.作用是指定命令搜索路径,在命令行下面执行命令如javac编译java程序时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序.我们需要把jdk安装目录下的bin目 ...
- 实现一个websocket常驻进程服务
由于工作的原因,近期调查了一下mac系统下常驻服务的接收websocket信息和创建进程的方法原理.将具体实现细节记录下来备忘. (一).准备工作 1.安装brew,在终端中输入: ruby -e & ...
- 机器学习实践之K-近邻算法实践学习
关于本文说明,本人原博客地址位于http://blog.csdn.net/qq_37608890,本文来自笔者于2017年12月04日 22:54:26所撰写内容(http://blog.csdn.n ...
- Python Django CMDB项目实战之-1如何开启一个Django-并设置base页、index页、文章页面
1.环境 win10 python 2.7.14 django 1.8.2 需要用到的依赖包:MySQLdb(数据库的接口包).PIL/pillow(处理图片的包) 安装命令: pip install ...
- JavaWeb核心技术学习 - 1.从JDBC说起
作者:java1to3链接:http://www.cnblogs.com/java1to3/著作权归作者所有.未经作者本人同意,禁止一切转载.商业或非商业转载请联系作者获得授权并请注明出处. ・JDB ...
- [乐意黎原创] cuteftp 9 显示中文乱码
当用FTP连接空间时.中文命名的文件名称会显示乱码,原来是编码设置错误.怎么改动呢? 改动方法例如以下: 选择. 工具--> 全局选项->传输: 1. 传输方法: ASCII 2. SFT ...