题目大意:略 题目传送门

不愧是$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+分治)的更多相关文章

  1. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  2. CF868F Yet Another Minimization Problem 分治决策单调性优化DP

    题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...

  3. 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)

    传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...

  4. 决策单调性优化dp 专题练习

    决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...

  5. [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)

    第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...

  6. BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】

    Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...

  7. CF868 F. Yet Another Minimization Problem 决策单调优化 分治

    目录 题目链接 题解 代码 题目链接 CF868F. Yet Another Minimization Problem 题解 \(f_{i,j}=\min\limits_{k=1}^{i}\{f_{k ...

  8. BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...

  9. 算法学习——决策单调性优化DP

    update in 2019.1.21 优化了一下文中年代久远的代码 的格式…… 什么是决策单调性? 在满足决策单调性的情况下,通常决策点会形如1111112222224444445555588888 ...

随机推荐

  1. 基于ffmpeg和libvlc的视频剪辑、播放器

    以前研究的时候,写过一个简单的基于VLC的视频播放器.后来因为各种项目,有时为了方便测试,等各种原因,陆续加了一些功能,现在集成了视频播放.视频加减速.视频剪切,视频合并(增加中)等功能在一起.有时候 ...

  2. 面向基于英特尔&#174; 架构的 Android* 的 CoCos2D

    Cocos2D 是一款游戏引擎,可与从电脑到手机等多种设备配合使用. 该引擎支持丰富的特性,可帮助创建出色的 2D 游戏.它甚至包含具备全面功能的物理引擎. CoCos2D 的核心元素是基本动画元素( ...

  3. XTU OJ 1207 Welcome to XTCPC (字符串签到题)

    Problem Description Welcome to XTCPC! XTCPC start today, you are going to choose a slogan to celebra ...

  4. 数据挖掘十大经典算法--CART: 分类与回归树

    一.决策树的类型  在数据挖掘中,决策树主要有两种类型: 分类树 的输出是样本的类标. 回归树 的输出是一个实数 (比如房子的价格,病人呆在医院的时间等). 术语分类和回归树 (CART) 包括了上述 ...

  5. Fitnesse安装

    Fitnesse安装比较简单 1.确保机器上已经安装了java环境

  6. Linux - xshell 链接CentOS 设置高亮

    默认是黑白的! 用了vim 指令还是黑白的. 两种途径设置,一种是通过Alt+P. 一种是选择配色方案来设置.

  7. php的mcrypt

    安装和使用php的mcrypt扩展 程序员们在编写代码程序时,除了要保证代码的高性能之外,还有一点是非常重要的,那就是程序的安全性保障.PHP除了自带的几种加密函数外,还有功能更全面的PHP加密扩展库 ...

  8. javascript设计模式-单体模式

    场景:假设有一个Girl(美女)实体,该实体拥有姓名.年龄两个属性,拥有显示姓名和洗澡两个方法,下面分步骤构造该实体. 1.用简单基本单体模式: var Girl1 = { name:"昭君 ...

  9. 利用python开发的flappy bird 游戏

    python 中 pygame模块能让我们很方便的编写游戏,16年我用python 仿制了flappy bird 游戏,下面是游戏的完整代码以及素材,分享给大家. 第一个python文件,flappy ...

  10. 运维自动化-Ansible

    前言 天天说运维,究竟是干什么的?先看看工作流程呗.一般来说,运维工程师在一家企业里属于个位数的岗位,甚至只有一个.面对生产中NNN台服务器,NN个人员,工作量也是非常大的.所以嘛,图中的我好歹也会配 ...