CTU Open Contest 2019 F题 Beer Marathon(思维题)

题目描述

CTU Open Contest 2019 F题 Beer Marathon(思维题)_第1张图片
CTU Open Contest 2019 F题 Beer Marathon(思维题)_第2张图片

题目大意

       有n个点排成一排,给出了它们的位置坐标,现在需要将它们按照相同的间隔k重新排列,问所有点需要移动的距离之和的最小值是多少?

分析过程

通过观察,可以发现两个小结论:

结论1   重新调整之后的排列至少存在一个位置与调整之前的相应位置重合。

可以用反证法证明:
       设原序列(升序排列之后的)集合为A,我们假设已经获得了一个满足最优方案的序列集合B,若对于 ∀ x ∈ A , ∀ y ∈ B \forall x\in A,\forall y\in B xA,yB均有 x ≠ y x\not=y x=y,此时,有3种情况:若A中的位置点 a i a_i ai大部分位于其对应位置 b i b_i bi的左侧时,此时我们将B向左移动一个单位必然可以使得结果更优(左边对减少距离的贡献更大);反之,向右移动更优,以上这两种情况均与假设中的“最优方案”矛盾;若A中的位置点均匀的散布在最优方案点的两侧,那么此时我们必然可以通过移动B而使得A与B之间存在相交点。综上所述,结论1得证。

结论2   由结论1的证明过程可以看出,在原序列中必然存在一个基准位置 a i a_i ai,当将序列 a 1 , a 1 + k , a 1 + 2 k , . . . , a 1 + ( n − 1 ) k a_1, a_1+k, a_1+2k, ..., a_1+(n-1)k a1,a1+k,a1+2k,...,a1+(n1)k中的对应位置(即 a i + ( i − 1 ) k a_i+(i-1)k ai+(i1)k)和 a i a_i ai对齐时,此时序列A中的点相对于间隔为 k k k的序列的相应位置点来说,左右散布是均匀的,此时我们就得到了最优方案,即题中所求。

       有了以上2个分析得到的结论做支撑之后,我们的问题就转化为了如何在原序列A中寻找基准位置。很显然一个一个枚举的时间复杂度是 O ( n 2 ) O(n^2) O(n2),必然要TLE。通过观察,我们发现,当把原序列A中的第一个位置作为基准位置时(选别的位置也行,但选第一个最方便),我们从左到右遍历一遍,将原序列A与标准序列 a 1 , a 1 + k , a 1 + 2 k , . . . , a 1 + ( n − 1 ) k a_1, a_1+k, a_1+2k, ..., a_1+(n-1)k a1,a1+k,a1+2k,...,a1+(n1)k分别作差。此时,差值处于中间的那个位置便是基准位置。(因为此时该位置能够均匀的将A序列各位置散布在 a 1 , a 1 + k , a 1 + 2 k , . . . , a 1 + ( n − 1 ) k a_1, a_1+k, a_1+2k, ..., a_1+(n-1)k a1,a1+k,a1+2k,...,a1+(n1)k 序列位置点的左右两侧)

       综上,我们得到的做法为:先将原序列x进行升序排列,与标准序列 a 1 , a 1 + k , a 1 + 2 k , . . . , a 1 + ( n − 1 ) k a_1, a_1+k, a_1+2k, ..., a_1+(n-1)k a1,a1+k,a1+2k,...,a1+(n1)k分别做差,最后找中间值确定基准位置,最后计算结果。时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)

附AC代码:

#include
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 1000;
ll x[maxn];
int main(){
	ll n,k,i,ans = 0;
	ios::sync_with_stdio(false);
	cin>>n>>k;
	for(i=1;i<=n;++i) cin>>x[i];
	sort(x+1,x+n+1);
	//判断在左对齐的情况下,每个点和标准点的相对位置(求差),符号为正说明在标准点右侧,否则在左侧 
	for(i=2;i<=n;++i){ 
		x[i] -= (i - 1) * k;
	}
	sort(x+1,x+n+1);
	ll mid = x[(1+n)/2];
	for(i=1;i<=n;++i) ans += abs(x[i] - mid);
	cout<

Another Solution

       如上文所述,实际上标准排列 a 1 , a 1 + k , a 1 + 2 k , . . . , a 1 + ( n − 1 ) k a_1, a_1+k, a_1+2k, ..., a_1+(n-1)k a1,a1+k,a1+2k,...,a1+(n1)k在原序列A中左右移动时,会使得总距离要么向左边方向增大,要么向右边方向增大,在其中间存在一个点取得最优方案。可以发现,这个总距离随坐标变化的图像是一个单峰曲线。因此,我们也可以使用三分法求解该问题。

你可能感兴趣的:(算法竞赛题解)