Luogu P2323「皇后游戏」

算是数论吧,证明出来一个公式之后就可以据此把所有大臣排序,然后求最后一位大臣的奖励即为答案。

证明:

考虑相邻的大臣是否交换。设某个编号为 $ 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值