对称山脉

有 N� 座山排成一排,从左到右依次编号为 1∼N1∼�。

其中,第 i� 座山的高度为 hiℎ�。

对于一段连续的山脉,我们使用如下方法定义该段山脉的不对称值。

如果一段连续的山脉由第 l∼r�∼�(1≤l≤r≤N1≤�≤�≤�)座山组成,那么该段山脉的不对称值为 ∑0≤i≤r−l2|hl+i−hr−i|∑0≤�≤�−�2|ℎ�+�−ℎ�−�|。

现在,你需要回答 N� 个问题,问题编号 1∼N1∼�。

其中,第 i� 个问题的内容是:请计算,一段恰好包含 i� 座山的连续山脉(即长度为 i� 的连续区间)的不对称值的最小可能值。

输入格式

第一行包含一个整数 N�。

第二行包含 N� 个整数 h1,h2,…,hNℎ1,ℎ2,…,ℎ�。

输出格式

输出一行 N� 个整数,其中第 i� 个数表示第 i� 个问题的答案。

数据范围

1≤N≤50001≤�≤5000,
0≤hi≤1050≤ℎ�≤105

输入样例1:
7
3 1 4 1 5 9 2
输出样例1:
0 2 0 5 2 10 10
样例1解释

关于第 55 个问题的答案为什么是 22,见如下解析。

让我们依次列举所有长度为 55 的连续区间并计算区间不对称值:

  • 区间 [3,1,4,1,5][3,1,4,1,5] 的不对称值为 |3−5|+|1−1|+|4−4|=2|3−5|+|1−1|+|4−4|=2。
  • 区间 [1,4,1,5,9][1,4,1,5,9] 的不对称值为 |1−9|+|4−5|+|1−1|=9|1−9|+|4−5|+|1−1|=9。
  • 区间 [4,1,5,9,2][4,1,5,9,2] 的不对称值为 |4−2|+|1−9|+|5−5|=10|4−2|+|1−9|+|5−5|=10。

由上可知,不对称值的最小可能值为 22。

输入样例2:
4
1 3 5 6
输出样例2:
0 1 3 7
样例2解释

注意,长度为 44 的连续区间只有 [1,3,5,6][1,3,5,6],其不对称值为 |1−6|+|3−5|=7|1−6|+|3−5|=7。

题解:

通过数据范围5000可以知道这道题最多需要使用O(n^2)的时间复杂度。

而我们可以通过找中心点来寻找答案,从中间向外扩展。时间复杂度O(n^2)

以下是代码:

#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int f[N],h[N];
int n;
int main(){
    cin>>n;
    for(int i=0;i<n;i++) scanf("%d",&h[i]);
    memset(f,0x3f,sizeof f);                       
    for(int i=0;i<n;i++)
    {
        //奇数
        for(int l=i,r=i,s=0;l>=0,r<n;l--,r++) 
        {
            s+=abs(h[r]-h[l]);
            f[r-l+1]=min(f[r-l+1],s);
        }
        //偶数
        for(int l=i,r=i+1,s=0;l>=0,r<n;l--,r++)
        {
            s+=abs(h[r]-h[l]);
            f[r-l+1]=min(f[r-l+1],s);
        }
    }
    for(int i=1;i<=n;i++)
    printf("%d ",f[i]);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值