BZOJ 4951 [WF2017]Money for Nothing (决策单调优化DP+分治)
题目大意:略 题目传送门
不愧是$World final$的神题,代码短,思维强度大,细节多到吐..调了足足2h
贪心
我们利用贪心的思想,发现有一些工厂/公司是非常黑心的
以工厂为例,对于一个工厂$i$,如果存在一个工厂$j$,$d_{j}<d_{i},p_{j}<p_{i}$,即出货比i早,而且比i便宜
那么不论我们选择任何消费公司,都一定会选$j$而不是选$i$
消费公司也用类似的贪心方法,消去那些黑心公司
以$d$为$x$轴,$p$为$y$轴,我们得到了许多在二维平面上的点,保证$d_{i}$递增,$p_{i}$递减
这一步贪心可以用单调栈实现
决策单调性
发现我们筛出来这些点以后,并没有什么卵用
假如把这个问题看成一个几何问题,题目转化为,能作为右上角的点视为白点,能作为左下角的点视为黑点,给定很多黑点白点,求白点作为右上角,黑点作为左下角,围成的矩形的面积最大值,且点集内的保证$d_{j}<d_{i},p_{j}<p_{i}$
以下讨论中,点的编号随横坐标$d$增大而增大
大胆地猜测一下,假设我们选择一个左下角黑点$i$,它对应的最优右上角白点是$j$,那么当$j-1$不能和$i$构成最优解时,点$i+1$能否和$j-1$构成最优解呢?
答案是不能,下面给出证明
我们已知$(x_{j}-x_{i})(y_{j}-y_{i})>(x_{j-1}-x_{i})(y_{j-1}-y_{i}),x_{i}<x_{i+1},y_{i}>y_{i+1},x_{j}<x_{j+1},y_{j}>y_{j+1}$
假如能构成最优解,那么$(x_{j-1}-x_{i+1})(y_{j-1}-y_{i+1})>(x_{j}-x_{i+1})(y_{j}-y_{i+1})$
把两式展开,消项可得
$x_{j}\cdot y_{j}-x_{i}\cdot y_{j}-x_{j}\cdot y_{i}>x_{j-1}\cdot y_{j-1}-x_{i}\cdot y_{j-1}-x_{j-1}\cdot y_{i}$
$x_{j-1}\cdot y_{j-1}-x_{i+1}\cdot y_{j-1}-x_{j-1}\cdot y_{i+1}>x_{j}\cdot y_{j}-x_{i+1}\cdot y_{j}-x_{j}\cdot y_{i+1}$
不等号方向相同,两式相加,消去相同项,可得
$-x_{i}\cdot y_{j}-x_{j}\cdot y_{i}-x_{i+1}\cdot y_{j-1}-x_{j-1}\cdot y_{i+1}>-x_{i}\cdot y_{j-1}-x_{j-1}\cdot y_{i}-x_{i+1}\cdot y_{j}-x_{j}\cdot y_{i+1}$
合并,整理可得
$(x_{i+1}-x_{i})(y_{j-1}-y_{j})+(y_{i}-y_{i+1})(x_{j}-x_{j-1})<0$
由于$x_{i}<x_{i+1},y_{i}>y_{i+1},x_{j}<x_{j+1},y_{j}>y_{j+1}$,上述式子一定大于$0$,所以这种情况不存在
分治求解
我们刚刚发现了这个优美的性质,接下来该如何利用这个性质求解呢?
考虑分治,用类似于整体二分的方法,把右上角的点看成询问,左下角的点视为操作(决策)
当前的询问区间是$[l1,r1]$,决策区间是$[l2,r2]$
现在选择了询问区间的重点$mid$,遍历$[l2,r2]$找到$mid$的决策$p$
根据决策单调性,$[l1,mid-1]$的决策一定属于$[l2,p]$,$[mid+1,r1]$的决策一定属于$[p,r2]$
类似于整体二分的方法,递归即可
繁多的细节
你作为中国代表队的一员参加了$ACM$,成功晋级$World Final$,然后你一眼看出了贪心,决策单调性,以及靠谱的分治算法,你抢过队友的键盘开始码这道题
不过这道题代码实现的细节还挺多的
首先,分治算法中,$mid$的决策$p$可能有多个,它们中的某几个可能同时作为$[l1,mid-1]$和$[mid+1,r1]$的决策
所以我们要把所有的决策$p$全都推到两边分治
但如果$mid$找不到决策怎么办?
找到最大的可能作为$[l1,mid-1]$和$[mid+1,r1]$的决策区间,继续递归
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 500010
#define ll long long
#define dd double
#define inf 1333333333
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
} int n,m,nn,mm; int stk[N1],tp; ll ans;
struct node{int x,v;}a[N1],b[N1],tmp[N1];
int cmp1(node s1,node s2){ if(s1.x!=s2.x) return s1.x<s2.x; return s1.v<s2.v; }
int cmp2(node s1,node s2){ if(s1.x!=s2.x) return s1.x<s2.x; return s1.v>s2.v; } int de;
void solve(int l1,int r1,int l2,int r2)
{
if(l1>r1||l2>r2) return;
int mid=(l1+r1)>>,i,S=-,E=-; ll ma=-,tmp;
for(i=l2;i<=r2;i++)
{
tmp=1ll*(b[mid].v-a[i].v)*(b[mid].x-a[i].x);
if(b[mid].x<a[i].x||b[mid].v<a[i].v) tmp=-inf;
if(tmp>ma) ma=tmp,S=E=i;
else if(tmp==ma) E=i;
}
if(S==-&&E==-)
{
de=;
if(l1<=mid+&&mid+<=r1)
for(i=l2;i<=r2;i++) if(b[mid+].v>=a[i].v){
solve(mid+,r1,i,r2); break; }
if(l1<=mid-&&mid-<=r1)
for(i=r2;i>=l2;i--) if(b[mid-].x>=a[i].x){
solve(l1,mid-,l2,i); break; }
return;
}
ans=max(ans,ma);
solve(l1,mid-,l2,E); solve(mid+,r1,S,r2);
} int main()
{
scanf("%d%d",&m,&n);
int i;
for(i=;i<=m;i++){ a[i].v=gint(); a[i].x=gint(); }
for(i=;i<=n;i++){ b[i].v=gint(); b[i].x=gint(); } sort(a+,a+m+,cmp1);
for(tp=,i=m;i;i--)
{
while(tp>=&&a[i].v<=a[stk[tp]].v) tp--;
stk[++tp]=i;
}
for(i=;i<=tp;i++) tmp[i]=a[stk[i]];
for(i=;i<=tp;i++) a[i]=tmp[tp-i+];
mm=tp; sort(b+,b+n+,cmp2);
for(tp=,i=;i<=n;i++)
{
while(tp>=&&b[i].v>=b[stk[tp]].v) tp--;
stk[++tp]=i;
}
for(i=;i<=tp;i++) tmp[i]=b[stk[i]];
for(i=;i<=tp;i++) b[i]=tmp[i];
nn=tp; solve(,nn,,mm);
printf("%lld\n",ans);
return ;
}
BZOJ 4951 [WF2017]Money for Nothing (决策单调优化DP+分治)的更多相关文章
- Lightning Conductor 洛谷P3515 决策单调性优化DP
遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...
- CF868F Yet Another Minimization Problem 分治决策单调性优化DP
题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...
- 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)
传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...
- 决策单调性优化dp 专题练习
决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...
- [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)
第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...
- BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】
Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...
- CF868 F. Yet Another Minimization Problem 决策单调优化 分治
目录 题目链接 题解 代码 题目链接 CF868F. Yet Another Minimization Problem 题解 \(f_{i,j}=\min\limits_{k=1}^{i}\{f_{k ...
- BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- 算法学习——决策单调性优化DP
update in 2019.1.21 优化了一下文中年代久远的代码 的格式…… 什么是决策单调性? 在满足决策单调性的情况下,通常决策点会形如1111112222224444445555588888 ...
随机推荐
- [bzoj4487][Jsoi2015]染色_容斥原理
染色 bzoj-4487 Jsoi-2015 题目大意:给你一个n*m的方格图,在格子上染色.有c中颜色可以选择,也可以选择不染.求满足条件的方案数,使得:每一行每一列都至少有一个格子被染色,且所有的 ...
- Vijos——T 1092 全排列
https://vijos.org/p/1092 描述 输入两个自然数m,n 1<=n<=20,1<=m<=n!输出n个数的第m种全排列. 如 :输入 3 1输出 1 2 3 ...
- 项目 cmdb(一)
Django之ModelForm组件 ModelForm a. class Meta: model, # 对应Mode ...
- 淘宝内部分享:MySQL & MariaDB性能优化
发表于2015-01-20 16:26| 28875次阅读| 来源mysql.taobao.org| 22 条评论| 作者淘宝数据库团队 MySQL性能优化淘宝数据库 摘要:MySQL是目前使用最多的 ...
- Camera-hal参数调整
路径: vendor/mediatek/proproetary/custom/mt6735/hal/D1/imgsensor/对应的SENSOR目录 .../D1/flashlight/flash_t ...
- linux中字符串转换函数 simple_strtoul
Linux内核中提供的一些字符串转换函数: lib/vsprintf.c 1. unsigned long long simple_strtoull(const char *cp, char **en ...
- Android——build.prop 解析【转】
本文转载自:http://blog.csdn.net/lengyue1084/article/details/77637354 一.概念 在Android设备shell终端可以看到/system目录下 ...
- bzoj5194: [Usaco2018 Feb]Snow Boots
还真是.. 就是 一个被不点名批评的垃圾骗分暴力选手被普及难度的省选信心(??)模拟赛艹爆的题解 的t3嘛... #include<cstdio> #include<iostream ...
- FH Admin
http://www.360doc.com/content/14/0713/08/8072791_394027312.shtml
- [源码管理] ubuntu下SVN服务器安装配置
一.SVN安装1.安装包$ sudo apt-get install subversion2.添加svn管理用户及subversion组$ sudo adduser svnuser$ sudo add ...