阿里巴巴2013实习生笔试题一算法题详解

题目:有一个淘宝商户,在某城市有n个仓库,每个仓库的储货量不同,现在要通过货物运输,将每次仓库的储货量变成一致的,n个仓库之间的运输线路围城一个圈,即1->2->3->4->...->n->1->...,货物只能通过连接的仓库运输,设计最小的运送成本(运货量*路程)达到淘宝商户的要求,并写出代码。

这个题目类似于下面的分糖果问题,这个问题在很多ACM比赛中都有出现,一些OJ系统上也有。

有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传

递一个糖果代价为1,求使所有人获得均等糖果的最小代价。

网上很多人的讲解大致都copy一个人的讲解,除此看可能半天无法理解,这里我详细的解析下。

分析:

假设a1,a2...an为当前每个仓库的货物,先把这些仓库放在一条线上,而不是环上来简化问题,可以如下考虑

设最终平均每个仓库货物为ave,则对第1个仓库,其目标存货量为eva,则其需要传递给a2仓库的货物为a1-eva

对于第2个仓库,目标同样为eva,需要传递给a3的货物为a2+(a1-eva)-eva=a1+a2-2*eva

以此类推,到了第n-1个仓库,需要传递给an仓库的货物为a1+a2+...+an-1 - (n-1)eva

此时虽然前n-1个仓库都达到了理想的eva的存货量,但是第n个仓库的存货量却不是eva,那么假设最后第n个仓库的货物量为k+eva,

如果此时恰好刚刚计算时,第1个仓库所设计的目标存货量为eva-k,则最后n仓库把k的货物移动到1仓库,则完成了目标。

于是重新假设,第1个仓库目标为eva-k,需要转移货物为a1-eva+k,于是第n-1个仓库需要转移货物为a1+a2+...+an-1 - (n-1)eva

最后n仓库转移k货物给1仓库。

则整个转移代价和为|a1+k-ave| |a1+a2+k-2*ave| |a1+a2+a3+k-3*ave||a1+..+a(n-1)+k-(n-1)*ave| |k|

以以s[i]表示从a1加到ai减掉i*ave的和,这上式可以化简为

总代价=|s1+k| |s2+k|...|sn-1+k| |k|

上式可以理解为一个s的数组,分布在数轴上,现在需要求s数组中每一个数,到-k这个数的距离最小,则只有当k为s的中位数的时候才满足。

上式也可以换个理解方式,前文中最后是n仓库移动k货物到1仓库,也可以变为从1仓库移动k货物到n仓库,这样上文中所有的k前面的符号变为负号

总代价=|s1-k| |s2-k|...|sn-1-k| |k|

这样更直观理解,当上式取最小时,k应该为s数组的中位数

具体实现的代码网上很多,可以自行百度。


你可能感兴趣的:(算法,阿里巴巴,笔试)