货仓选址

题目

题目

讲解

假设我们现在这个货仓建立在\((a[i],a[i+1])\)之间(注意,不是\([a[i],a[i+1]]\)),那么我们向右移动,整个距离变化是:\((n-i)-i=n-2*i\),而向右移动是\(i-(n-i)=2*i-n\),所以当\(n-2*i=0\)时,说明没有办法再让结果增大或者减少了,此时\(i=\frac{n}{2}\)(而且画个图也不难看出,距离和随着货舱位置的变化呈现出一个单峰函数),所以就选择\(i-(i+1)\)之间,当然,我们选择在\(i+1\)放货舱,反正只要在\([a[i],a[i+1]]\)放结果都是一样的,而且不难得出,在其他位置放,都可以向左移动或者向右移动使距离和变小,并最终移动到这个区间当中。

但是如果\(n\)是奇数呢,再来考虑一种情况:货舱放在了\(i\)的位置,向左移动距离和增加:\((n-i+1)-(i-1)=n-2*i+2\),向右移动为\(i-(n-i)=2*i-n\),那么当这两个都大于等于\(0\)时最大,不难得出\(i=\frac{n}{2}+1\),而且不难发现放在其他位置都可以向左向右移动使得距离和变小,并且最终都会移动到中位数的位置,也就是\(\frac{n}{2}+1\)的位置。

所以不难看出,我们只要放在\(\frac{n}{2}+1\)的位置就可以了。

时间复杂度:\(O(nlogn)\)(要排序啊QAQ)

听说有\(O(n)\)做法,知道的奆佬分享给我可以吗QAQ(有博客链接最好)。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define  N  2100000
using  namespace  std;
typedef  long  long  LL;
LL  a[N];
int  n;
inline  LL  zabs(LL  x){return  x<0?-x:x;}
int  main()
{
	scanf("%d",&n);
	for(int  i=1;i<=n;i++)scanf("%lld",&a[i]);
	sort(a+1,a+n+1);
	LL  x=a[n/2+1],ans=0;
	for(int  i=1;i<=n;i++)ans+=zabs(a[i]-x);
	printf("%lld\n",ans);
	return  0;
}
posted @ 2020-07-30 15:15  敌敌畏58  阅读(114)  评论(0编辑  收藏  举报