CF102920L Two Buildings【分治】【决策单调性】
优秀的分治题目。是“2020-2021 ACM-ICPC, Asia Seoul Regional Contest”的一道题。
Description
There are \(n\) buildings along a horizontal street. The buildings are next to each other along the street, and the \(i\)-th building from left to right has width \(1\) and height \(h_i\). Among the \(n\) buildings, we are to find two buildings, say the \(i\)-th building and \(j\)-th building with \(i<j\), such that \((h_i+h_j)*(j−i)\) is maximized.
For example, the right figure shows \(5\) buildings, with heights \(1\), \(3\), \(2\), \(5\), \(4\), from left to right. If we choose the first \(2\) buildings, then we get \((1+3)*(2−1)=4\). If we choose the first and fifth buildings, then we \((1+4)*(5−1)=20\). The maximum value is achieved by the second and fifth buildings with heights \(3\) and \(4\), respectively: \((3+4)*(5−2)=21\).
Write a program that, given a sequence of building heights, prints \(\max_{1\le i<j\le n}(h_i+h_j)*(j−i)\).
Input
Your program is to read from standard input. The input starts with a line containing an integer \(n\) (\(2\le n\le 1,000,000\)), where \(n\) is the number of buildings. The buildings are numbered \(1\) to \(n\) from left to right. The second line contains the heights of \(n\) buildings separated by a space such that the \(i\)-th number is the height \(h_i\) of the \(i\)-th building (\(1\le h_i\le 1,000,000\)).
Output
Your program is to write to standard output. Print exactly one line. The line should contain \(\max_{1\le i<j\le n}(h_i+h_j)*(j−i)\).
Examples
input
5
1 3 2 5 4
output
21
input
5
8 3 6 3 1
output
36
题意:
有 \(n(2\le n\le 1000000)\) 栋楼房,第 \(i\) 栋高度为 \(h_i(1\le h_1\le 1000000)\)。问两栋楼房所能构成的 \((h_i+h_j)*(j−i)\) 最大值是多少。
题解:
为了方便,我们把要求的式子转化为 \((h_i-(-h_j))\times(j-i)\),这样构造出数列 \(-h_i\),就是坐标系中 \(x\) 轴上方和 \(x\) 轴下方两个数列中选出两个 \(h\) 进行计算。
如果存在 \(i<j\),同时 \(-h_i<-h_j\),那么 \(j\) 一定比 \(i\) 更优。可以用单调栈来把数列 \(\{h_i\}\) 和 \(\{-h_i\}\) 都变为单调的。得到单增的 \(\{H_i\}\) 和 \(\{-H_i\}\)。
如图,图中橙色的点删除后,对答案产生贡献的点只会在蓝色中产生。
而蓝色的点 \(\{H_i\}\) 和 \(\{-H_i\}\) 对应了两段递增的序列(此时下标 \(i\) 不一定连续)。最终答案为 \([H_i-(-H_j)]\times(j-i)\)。假设对于选定的 \(H_i\),对应 \(-H_j\) 为最优解,即 \(\forall k>j,[H_i-(-H_j)]\times(j-i)\geqslant[H_i-(-H_k)]\times(k-i)\),可知
[H_i-(-H_j)]\times(j-i)&\geqslant[H_i-(-H_k)]\times(k-i)\\\
[H_i-(-H_j)]\times(j-i)\color{red}{-[H_i-(-H_k)]\times(j-i)}&\geqslant[H_i-(-H_k)]\times(k-i)\color{red}{-[H_i-(-H_k)]\times(j-i)}\\\
[(-H_k)-(-H_j)]\times(j-i)&\geqslant[H_i-(-H_k)]\times(k-j)
\end{aligned}\]
因此对于 \(l<i\),对上式进行放缩,得
[(-H_k)-(-H_j)]\times(j-i)&\geqslant[H_i-(-H_k)]\times(k-j)\\\
[(-H_k)-(-H_j)]\times(j-i)\color{blue}{+[(-H_k)-(-H_j)]\times(i-l)}&\geqslant[H_i-(-H_k)]\times(k-j)\color{red}{-(H_i-H_l)\times(k-j)}\\\
[(-H_k)-(-H_j)]\times(j-l)&\geqslant[H_l-(-H_k)]\times(k-j)\\\
[(-H_k)-(-H_j)]\times(j-l)\color{blue}{+[H_l-(-H_k)]\times(j-l)}&\geqslant[H_l-(-H_k)]\times(k-j)\color{blue}{+[H_l-(-H_k)]\times(j-l)}\\\
[H_l-(-H_j)]\times(j-l)&\geqslant[H_l-(-H_k)]\times(k-l)
\end{aligned}\]
所以当 \(H_i\) 对应的最优解位置为 \(-H_j\) 时,\(l<i\) 的 \(H_l\) 对应的最优解位置 \(-H_k\) 满足 \(k\geqslant j\)。
如果上式推导过于复杂,它对应的图形推导如下。
左图中,如果 \(H_i\) 对应的最优解是 \(H_j\),那么①的面积 \(S_1\) 一定比②的 \(S_2\) 大。右图中,那么对 \(l<i\),已知 \(S_1\geqslant S_2\),有 \(S_1+S_3\geqslant S_2-S_4\),所以 \(l\) 对应的最优解一定不会在 \(j\) 右边。
此时再考虑上边的推导,便能清楚理解了。
分治递归,时间复杂度为 \(O(n\log n)\)。
Code:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
int a[1001000],b[1001000],c[1001000];
int bp[1001000],cp[1001000];
ll ans=0;
void solve(int l,int r,int L,int R)
{
if(l>r)
return;
int mid=(l+r)>>1,q=0;
ll Ans=0;
for(int i=L;i<=R;++i)
{
if(Ans<1ll*(cp[i]-bp[mid])*(b[mid]+c[i]))
{
q=i;
Ans=1ll*(cp[i]-bp[mid])*(b[mid]+c[i]);
}
}
ans=ans>Ans?ans:Ans;
solve(l,mid-1,L,q);
solve(mid+1,r,q,R);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
int ii=0,iii=0;
c[0]=1e8;
for(int i=1;i<=n;++i)
{
if(a[i]>b[ii])
{
b[++ii]=a[i];
bp[ii]=i;
}
while(a[i]>=c[iii])
--iii;
c[++iii]=a[i];
cp[iii]=i;
}
solve(1,ii,1,iii);
printf("%lld\n",ans);
return 0;
}
CF102920L Two Buildings【分治】【决策单调性】的更多相关文章
- CF868F Yet Another Minimization Problem 分治决策单调性优化DP
题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...
- bzoj2216: [Poi2011]Lightning Conductor(分治决策单调性优化)
每个pi要求 这个只需要正反DP(?)一次就行了,可以发现这个是有决策单调性的,用分治优化 #include<iostream> #include<cstring> #incl ...
- [BZOJ2739]最远点(DP+分治+决策单调性)
根据旋转卡壳,当逆时针遍历点时,相应的最远点也逆时针转动,满足决策单调性.于是倍长成链,分治优化DP即可,复杂度O(n^2). #include<cstdio> #include<a ...
- BZOJ2739 最远点(分治 + 决策单调性)
2739: 最远点 Time Limit: 20 Sec Memory Limit: 256 MB Description 给你一个N个点的凸多边形,求离每一个点最远的点. Input 本题有多组数据 ...
- 决策单调性&wqs二分
其实是一个还算 trivial 的知识点吧--早在 2019 年我就接触过了,然鹅当时由于没认真学并没有把自己学懂,故今复学之( 1. 决策单调性 引入:在求解 DP 问题的过程中我们常常遇到这样的问 ...
- CodeForces 868F Yet Another Minimization Problem(决策单调性优化 + 分治)
题意 给定一个序列 \(\{a_1, a_2, \cdots, a_n\}\),要把它分成恰好 \(k\) 个连续子序列. 每个连续子序列的费用是其中相同元素的对数,求所有划分中的费用之和的最小值. ...
- P2877 [USACO07JAN]牛校Cow School(01分数规划+决策单调性分治)
P2877 [USACO07JAN]牛校Cow School 01分数规划是啥(转) 决策单调性分治,可以解决(不限于)一些你知道要用斜率优化却不会写的问题 怎么证明?可以暴力打表 我们用$ask(l ...
- 洛谷CF868F Yet Another Minimization Problem(动态规划,决策单调性,分治)
洛谷题目传送门 貌似做所有的DP题都要先搞出暴力式子,再往正解上靠... 设\(f_{i,j}\)为前\(i\)个数分\(j\)段的最小花费,\(w_{l,r}\)为\([l,r]\)全在一段的费用. ...
- bzoj 2739 最远点——分治处理决策单调性
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2739 分治处理决策单调性的思想就是先找到一个询问,枚举所有可能的转移找到它的决策点,那么这个 ...
- 4951: [Wf2017]Money for Nothing 决策单调性 分治
Bzoj4951:决策单调性 分治 国际惯例题面:一句话题面:供应商出货日期为Ei,售价为Pi:用户收购截止日期为Si,收购价格为Gi.我们要求max((Si-Ej)*(Gi-Pj)).显然如果我们把 ...
随机推荐
- 静默安装Oracle也没那么恐怖
几种必须静默安装的情况 服务器为了减少资源占用,没安装图形组件 不能进入机房,只能远程SSH 想炫(Z)耀(B),静默安装显得有技术含量 磁盘分区要求 如没有特别要求,装机时可按如下分区比较好管理 / ...
- GitLab开发流程图示、Git命令一张图
GitLab开发流程图示.Git命令一张图 一.GitLab开发流程图示 二.Git命令一张图 作图工具:ProcessOn 一.GitLab开发流程图示 二.Git命令一张图
- JavaWeb——Cookie,Session学习汇总
什么是Cookie Cookie的作用 安全性能 Cookie的语法 Cookie注意细节 Cookie实例练习 什么是会话Session Session语法 Session与浏览器窗口的关系 ses ...
- Spring框架——IOC&DI
Spring Spring 目标 内容 Spring与web整合的原理 Spring 中包含的关键特性 Spring架构图 企业级框架 企业级系统 IOCDI IOC DI IOC和DI 为什么使用依 ...
- 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。
package com.minxinloan.utils; import java.math.BigDecimal; public class Arith { // 源文件Arith.java: /* ...
- MB与Mb
MB/s的含义是兆字节每秒,Mbit/s的含义是兆比特每秒,前者是指每秒传输的字节数量,后者是指每秒传输的比特位数.即B=Byte,b=bit,1Byte=8bit.下载时用的是B,交换机上用的是b, ...
- 设计模式(十四)——模板模式(SpringIOC源码分析)
1 豆浆制作问题 编写制作豆浆的程序,说明如下: 1) 制作豆浆的流程 选材--->添加配料--->浸泡--->放到豆浆机打碎 2) 通过添加不同的配料,可以制作出不同口味的豆浆 3 ...
- Codeforces Round #683 (Div. 2, by Meet IT)【ABCD】
比赛链接:https://codeforces.com/contest/1447 A. Add Candies 题意 \(1\) 到 \(n\) 个袋子里依次有 \(1\) 到 \(n\) 个糖果,可 ...
- 关于cnblogs至github上blog的搬迁
由于同学的强烈抗议(由于网页太卡,而且还有bug),所以在今天完成了github上blog的搭建,并且有了良好的阅读环境; Leceue
- Codeforces Round #650 (Div. 3) B. Even Array
题目链接:https://codeforces.com/contest/1367/problem/B 题意 有一大小为 $n$ 的数组 $a$,问能否经过交换使所有元素与下标奇偶性相同(0 - ind ...