题目大意:
有一串数字对{ (a1,b1),(a2,b2) } An
现在有一个计算分数的算法:
第i个人的分数:score[i]=king*An[0][0]*An[1][0]*..A[i-1][0]/A[i][1]。
其中,king表示一个初始值,题目给定的。
问:我们对An的数对任意排列,怎么得到每次排列中score最大的那个 最小。并输出最优的score
解题思路:
假设我们只有一个数字对。
(a1,b1),那么score只有一个,显然只有一个解
假设有两个数字对。
(a1,b1),(a2,b2),那么我们只有两种排法。
ans1=max(king/b1,king*a1/b2)
ans2=max(king/b2,king*a2/b1)
假设ans1<ans2,我们得到a1*b1<a2*b2。
所以,若我们想得到ans1的结果,那么第一个数字的a*b一定要小于后一个数字的a*b。
所以,我们按照a*b从小到大排序,最终的排序结果就是最优解,我们可以得到这种排列的分数最大值。
现在的问题是:这种排法只是一种局部最优,对于An中有3个或者以上的数字对,我们怎么证明这种排法可以达到全局最优!
假设有三个数字对e1,e2,e3。
按照上述算法,我们的排列为:
e1 e2 e3,这样是最优的。
那么我们有个疑问,是否可以e2 e1 e3来排布呢?
我们可以发现,换一种排布方式对于第三个数字对而言是没差的,但是前两个数字对却更差了!最终结果可能会更差。
所以把n=3往后推广,我们证明了,局部最优的排布可以到达全局最优排布。
废话:
这种贪心题,一定要想办法构造出局部最优,并且可以推广到全局最优。
问题是这种局部最优往往难以构造,例如这题,我们需要用一定的公式推导,这也是贪心的困难之处。
python: