算是数论吧,证明出来一个公式之后就可以据此把所有大臣排序,然后求最后一位大臣的奖励即为答案。
证明:
考虑相邻的大臣是否交换。设某个编号为 $ i $ 的大臣,后面一位编号为 $ j $ 。设i前面所有大臣的 $ a $ 值之和为 $ x $ ,设 $ c[i-1] $ 为 $ y $ 。如果不交换 $ i $ 和 $ j $ ,则 $ c $ 值较大的大臣的 $ c $ 值为
$ max(max(x+a_i,y)+b_i,x+a_i+a_j)+b_j $
化简:
$ max(x+a_i+b_i+b_j,,y+b_i+b_j,x+a_i+a_j+b_j) $
同理,如果交换,则较大的C值为
$ max(max(x+a_j,y)+b_j,x+a_i+a_j)+b_i $
化简:
$ max(x+a_j+b_i+b_j,y+b_i+b_j,x+a_i+a_j+b_i) $
即:
交换后两大臣的最大奖励和=$ max(x+a_j+b_i+b_j,y+b_i+b_j,x+a_i+a_j+b_i) $①
不交换两大臣的最大奖励和=$ max(x+a_i+b_i+b_j,y+b_i+b_j,x+a_i+a_j+b_j) $②
假设交换后的情况优于不交换,即①<=②,那么就交换两大臣位置。此时有:
$ max(x+a_j+b_i+b_j,y+b_i+b_j,x+a_i+a_j+b_i) $ <= $ max(x+a_i+b_i+b_j,y+b_i+b_j,x+a_i+a_j+b_j) $ ③
化简(删去公共项$ y+b_i+b_j $):
$ max(x+a_j+b_i+b_j,x+a_i+a_j+b_i) $ <= $ max(x+a_i+b_i+b_j,x+a_i+a_j+b_j) $ ④
继续化简(消去$ x $)
$ max(a_j+b_i+b_j,a_i+a_j+b_i) $ <= $ max(a_i+b_i+b_j,a_i+a_j+b_j) $ ⑤
继续化简(左右两边提出各自系数)
$ max(a_i,b_j)+a_j+b_i $ <= $ max(a_j,b_i)+a_i+b_j $ ⑥
移项:
$ max(a_i,b_j)-a_i-b_j $ <= $ max(a_j,b_i)-a_j-b_i $ ⑥
得出
$ -min(a_i,b_j) $ <= $ -min(a_j,b_i) $ ⑦
$ min(a_i,b_j) $ >= $ min(a_j,b_i) $ ⑧
也就是说,当两个相邻的大臣,其$ a_i,b_i,a_j,b_j $满足⑧时,此时交换后的情况优于不交换。于是此时交换 $ i,j $。
代码实现的话,就是写一个sort用的cmp函数:
bool cmp(const nd &x,const nd &y){
int ai=x.a,bi=x.b,aj=y.a,bj=y.b;
return min(bi,aj)>min(ai,bj);
}
注意这里要写成>而不是>=,否则会数组越界导致RE。
用这个cmp,sort一波之后从1到n算出 $ C[1-n] $ ,最后因为C单调递增,所以$ C[n] $ 最大,既为答案。
原文地址:https://www.cnblogs.com/soul-M/p/9567592.html