Cow coupons
先说明做法:
首先将所有奶牛按照\(c\)升序排序,那么最终答案一定包含\(c\)最小的前\(k\)个奶牛(如若不然,设前\(k\)个奶牛中,第\(i\)头奶牛没有在最终方案中,而最终方案中一定有一头用了优惠券的奶牛\(j\)的\(c\)比\(i\)的\(c\)大,于是我们不买\(j\),选择用优惠券买\(i\),显然用的钱更少)
开三个优先队列(都是小根堆)\(q_,q_2,q_3\),分别表示还没有购买的奶牛的原价,还没有购买的奶牛的优惠价以及已经购买了的且使用了优惠券的奶牛的原价减去优惠价
我们认为已经买了的奶牛是一定不会不买的,我们只需要考虑优惠券的转移;现在我们想要多买一头奶牛,如果我们用原价买这头奶牛,就选择\(q_1\)的堆顶,如果我们要用优惠券买这个奶牛,那么优惠券就要发生转移,于是考虑\(q_2\)的堆顶加上\(q_3\)的堆顶,并将新的用了优惠券的奶牛的原价减优惠价加入\(q_3\),所以比较\(q_1\)的堆顶和\(q_2\)的堆顶加上\(q_3\)的堆顶即可;然后重复以上过程直到钱不够用了
以上只是直觉,缺少严格证明,下面证明:
假设我们已经买了的奶牛集合\(A\)在最终方案中一定都会买(即不后悔奶牛是否买),并且对于已经买了的奶牛,优惠券的分配是最优的,那么如果我们想要多买一头奶牛,下面只分析\(q_1\)的堆顶小于\(q_2\)的堆顶加上\(q_3\)的堆顶(反之同理分析):设\(q_1\)堆顶代表的奶牛是\(i\),如果我们最终方案中不买\(i\),那么对于最终方案中不属于\(A\)的奶牛,如果都是以原价买的,那么显然随便舍弃一头奶牛买\(i\)都更优,如果存在奶牛\(j\)用了优惠券,那么这个优惠券一定是从\(A\)中用了优惠券的奶牛身上转移过来的,然而我们有\(q_1\)的堆顶小于\(q_2\)的堆顶加上\(q_3\)的堆顶,\(q_2\)的堆顶加上\(q_3\)的堆顶小于将优惠券转移到\(j\)上所产生的价格,所以\(q_1\)的堆顶小价格于将优惠券转移到\(j\)上所产生的价格,于是我们将“将优惠券转移到\(j\)上”变成“买\(i\)并且不转移优惠券”显然是一种更优的方案,所以\(i\)是一定要买的
update 2024.7.22