题目大意:

有一串数字对{ (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:

n=int(input())
fin=[]
king=input().split(" ")
king=[int(king[0]),int(king[1])]
for i in range(n):
nol=input().split(" ")
no1=int(nol[0])
no2=int(nol[1])
fin.append([no1,no2])

fin.sort(key=lambda x: x[0]*x[1])
fac=king[0]
ans=-1
for i in range(n):
if i:
fac*=fin[i-1][0]
tmpans=fac//fin[i][1]
ans=max(tmpans,ans)
print(ans)