gym102920 L. Two Buildings(决策单调性+分治)

这篇博客探讨了一种计算给定数组中最大矩形面积的方法。通过将问题转化为寻找两个子数组之间的最大矩形面积,并利用分治策略进行递归计算。文章详细介绍了算法的实现过程,包括如何找到最优匹配点,以及如何删除无效数据,最终通过代码展示了如何在O(n log n)的时间复杂度内解决该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

给定长度为n的数组h,
要求计算max{(h[i]+h[j])*(j-i)},其中i<j.

数据范围:n<=1e6,1<=h(i)<=1e6

解法:
(h[i]+h[j])*(j-i)
=(h[j]-(-h[i]))*(j-i)

令a[i]=h[i],b[i]=-h[i],
那么可以转化为计算(a[j]-b[i])*(j-i),
转化为(i,a[i]),(j,b[j])在二维坐标系中围成的矩形面积.

对于一个固定的(j,a[j]),选择的(i,b[i])显然位置右下越优.
那么对于(i,b[i])(j,b[j]),如果i<j且b[i]>b[j],
那么(i,b[i])完全可以删去,
去掉b[]无用点之后,剩下的点一定是对于i<j,有b[i]<b[j],
同理a[]去掉无用点之后,剩下的点一定是对于i<j,有a[i]>b[j].

那么坐标图大概是这样的:
在这里插入图片描述

对于a[1,n],设mid=(l1+r1)/2,
设点(mid,a[mid])在点(pos,b[pos])处获得最大值.

如图示:
在这里插入图片描述

那么对于(mid,a[mid])左边的点(j,a[j]),
他们的最优解点(i,b[i])一定满足i<=pos,
可以用反证法证明,
大概就是如果i>pos,那么(mid,a[mid)的就不是(pos,b[pos]),
画一下图应该也能证明出来.
假设现在我们已经求出(mid,a[mid])(pos,b[pos])配对最优,
根据我们上面的结论,我们只需要继续分别计算:
1.a[l1,mid-1]和b[l2,pos]匹配的最大值.
2.a[mid+1,r2]h和b[pos,r2]匹配的最大值.(mid,a[mid])(pos,b[pos])的值,三者取max就是答案,
其中情况1和情况2是子问题,可以递归计算.
code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e6+5;
struct Node{
    int x,y;
}a[maxm],b[maxm];
int del[maxm];
int h[maxm];
int n,m;
bool cmp(Node a,Node b){
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}
int cal(int j,int i){
    return (a[j].y-b[i].y)*(a[j].x-b[i].x);
}
int solve(int l1,int r1,int l2,int r2){
    if(l1>r1||l2>r2)return -1e18;
    int mid=(l1+r1)/2;
    int pos=l2;
    int ma=cal(mid,pos);
    for(int i=l2+1;i<=r2;i++){
        int temp=cal(mid,i);
        if(temp>=ma){
            ma=temp;
            pos=i;
        }
    }
    return max(ma,max(solve(l1,mid-1,l2,pos),solve(mid+1,r1,pos,r2)));
}
signed main(){
    ios::sync_with_stdio(0);
    cin>>n;
    m=n;
    for(int i=1;i<=n;i++){
        cin>>h[i];
        a[i]={i,h[i]};
        b[i]={i,-h[i]};
    }
    sort(a+1,a+1+n,cmp);
    sort(b+1,b+1+n,cmp);
    //去掉a数组无用数据
    for(int i=1;i<=n;i++)del[i]=0;
    int last=n,cnt=0;
    for(int i=n-1;i>=1;i--){
        if(a[i].y<=a[last].y){
            del[i]=1;
        }else{
            last=i;
        }
    }
    for(int i=1;i<=n;i++){
        if(!del[i]){
            a[++cnt]=a[i];
        }
    }
    n=cnt;
    //去掉b数组无用数据
    for(int i=1;i<=m;i++)del[i]=0;
    last=1,cnt=0;
    for(int i=2;i<=m;i++){
        if(b[i].y>=b[last].y){
            del[i]=1;
        }else{
            last=i;
        }
    }
    for(int i=1;i<=m;i++){
        if(!del[i]){
            b[++cnt]=b[i];
        }
    }
    m=cnt;
    //分治计算答案
    int ans=solve(1,n,1,m);
    cout<<ans<<endl;
    return 0;
}

自2020年以来,自动驾驶汽车(Autonomous Vehicle)在这一领域取得了显著进展。 自动驾驶汽车通过使用先进的传感技术,如雷达、激光雷达和摄像头,以及深度学习和人工智能算法,实现了车辆的自主驾驶。它们能够感知周围环境,了解道路状况,并做出相应的决策和行驶动作,从而实现无需人类操控的车辆行驶。 自动驾驶汽车在2020年迅速崭露头角。它们的技术日益成熟,不断的实验和测试表明其在安全性和性能方面已经取得了显著的突破。虽然仍然存在一些挑战,比如在复杂城市环境中导航和处理紧急情况,但这些问题正经过不断的研究和改进来得以解决。 在未来,自动驾驶汽车有望在各个领域发挥重要作用。首先,它们将可以提高道路交通的安全性。由于自动驾驶车辆不受人类司机的疲劳、分心和驾驶误差的限制,它们的驾驶能力更为稳定和准确。其次,自动驾驶汽车还能够提高交通效率。通过与其他车辆实时通信和协同,它们可以避免交通堵塞和减少事故发生,从而减少交通拥堵和行车时间成本。 此外,自动驾驶汽车也将为交通出行带来便利和舒适性。乘客可以更轻松地进行其他活动,如工作、休息或娱乐,而不必担心驾驶问题。老年人和残障人士也将能够自由独立地出行,提高他们的生活质量。 综上所述,作为2020年的重要趋势,自动驾驶汽车具有广阔的应用前景。通过不断的创新和发展,它们将在道路交通安全、交通效率和出行体验方面取得进一步的提升。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值