NKOJ P5608 求和

给定一个整数数列,要求找到一个整数X,使数列中每个元素与X+i的绝对差之和最小。解决方法是先将数列减去各自的索引,然后找出新数列的中位数作为X,以达到最小和。代码实现中,首先对调整后的数列进行排序,然后根据奇偶性确定中位数,最后计算绝对差之和。

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

何老板有一个长度为NNN的整数数列AAA
他让你任选一个整数xxx,使得下面式子的值最小:
∣A1−(X+1)∣+∣A2−(X+2)∣+∣A3−(X+3)∣+......+∣AN−(X+N)∣|A_1-(X+1)|+|A_2-(X+2)|+|A_3-(X+3)|+......+|A_N-(X+N)|A1(X+1)+A2(X+2)+A3(X+3)+......+AN(X+N)
请你计算出上面式子的最小值。

分析

这道题不算太难,但要提前知道一个知识点:

对于形如∣a1−y∣+∣a2−y∣+......+∣an−y∣|a_1-y|+|a_2-y|+......+|a_n-y|a1y+a2y+......+any式子,当其为最小值时,yyy当且仅当为序列aaa的中位数

那我们只需要对上式拆开括号就可以变成这种形式:∣Ai−(X+i)∣=∣(Ai−i)−X∣|A_i-(X+i)|=|(A_i-i)-X|Ai(X+i)=(Aii)X其中Ai−iA_i-iAii是个定值,可以被提前求出;

现在就好办了,我们只需要把AiA_iAi预处理成Ai−iA_i-iAii,然后求出新序列的中位数即是XXX的值,最后带入求解即可;

时间复杂度O(Nlog⁡N)O(N\log N)O(NlogN),可以通过(求中位数时要排序!)

Code

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
int n,a[200005],ans,num;
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){scanf("%lld",&a[i]);a[i]-=i;}
	sort(a+1,a+n+1);
	if(n&1){num=a[n/2+1];}
	else{num=(a[n/2]+a[n/2+1])/2;}
	for(int i=1;i<=n;i++){ans+=abs(a[i]-num);} 
	printf("%lld",ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值