发现我自己好像不太会做这种题目
但是还是发现有一些套路的
就是拿出中间相邻的两项来进行比较
我们拿出(i,j)这相邻的两项,设(x)表示所有排在(i)还有(j)之前的人左手上的数的乘积,那么(i)在前的充分条件是
[frac{x*a_i}{b_j}<frac{x*a_j}{b_i}
]
前面那个柿子是(i)排在前面时(j)能获得的收益,后面则是(j)排在前面的收益
我们继续化一下柿子
[a_i*b_i<a_j*b_j
]
所以我们以(a_i*b_i)为关键字从小到大排序就好了
之后还有一些非常相似的题目
比如说排队接水这种非常入门的题目了
有n个人在一个水龙头前排队接水,假如每个人接水的时间为ai,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小。
首先但凡有点常识的人应该都知道这个时候应该尽量让接水时间少的人在前,这也非常好感性理解,但是我们同样也可以使用上面的那个方法来说明这一点
我们设(i,j)为相邻的两个人,那么(i,j)之前所有人的总接水时间为(s),如果(i)排在(j)前面,则需要满足
[s+s+a_i<s+s+a_j
]
(s+a_i)是(i)排在前面(j)的等待时间,(s+a_j)是(j)排在前面(i)的等待时间
根据上面那个柿子我们可以推出(a_i<a_j),于是我们就应该以(a_i)为关键字从小到大排序
这个问题还有一个强化版,就是给每一个排队接水的人加上了一个权(b_i),要求使得(sum_{i=1}^npre_i*b_i)最小,(pre_i)为第(i)个人的等待总时间
我们还是按照刚才的套路来,设(i,j)为相邻两人,(i,j)之前所有人的总接水时间为(s),如果(i)排在(j)前面,则需要满足
[s*b_i+(s+a_i)*b_j<s*b_j+(s+a_j)*b_i
]
那么就有
[s*b_i+s*b_j+a_i*b_j<s*b_j+s*b_i+a_j*b_i
]
于是就有
[a_i*b_j<a_j*b_i
]
也就是
[frac{a_i}{b_i}<frac{a_j}{b_j}
]
所以我们以(frac{a_i}{b_i})为关键字从小到大排序就好了
我好像还没有写国王游戏,需要高精度实在是恶心