阿里巴巴2013笔试最后一题解答

来源:互联网 发布:js apply的z作用 编辑:程序博客网 时间:2024/05/17 22:18
题目描述:一个淘宝金冠卖家有n个仓库,每个仓库存储量不同,他想通过搬运使得所有仓库存储量相等,n个仓库形成环状,搬运只在相邻仓库间发生,请设计高效算法达到卖家的目的,并且使得总搬运量最低。

分析:设每个仓库库存为a[i],第i个仓库搬给其右边的仓库x[i]个。m为最后每个仓库库存。可有方程
m = a1 - x1 + x2
= a2 - x2 + x3
=﹉
= an - xn + x1
x2 = m - a1 + x1 = x1 - c1
x3 = m - a2 + x2 = x1 - c1 + m - a2 = x1 - c2
x4 = x1 - c4

xn = x1 - cn
问题为求出x数组使得所有元素之和最小,只要求出x1即可。ci为已知,所以问题可转化为数轴上n个点ci,求出一点使得其到各个点的距离之和最短。可以证明所有点的中间点即为最解。简单证明如下:
设最解点为k,如果k不是最中间点,则必然其两边有的点数不同,不妨设右边点数多于左边,为了更具体,不妨设左边有2个点,右边有3个点,现在使k向右移动d个单位,则左边所有点到k的总距离将增加2d个单位,而右边减少3d个单位,总距离减少d个单位,显然k不是最优解,当k右移至中间点时,此时无论左移或右移都会增加总距离,故中间点为最优解。
以上证明并不严谨,但足以说明最优解。
程序如下
int foo(int a[]){for(i : 0——n)sum += ai;m= sum / n;c0=a1 - m;for(i:1——n)ci = c[i-1] + ai - m;sort(c, c+n);x0 = c[n/2];sum = x0;for(i:1——n){xi = x0 - ci;sum += xi;}return sum;}

时间复杂度o(nlogn).,若有朋友发现错误,欢迎指正,共同学习。
原创粉丝点击