Cow coupons

先说明做法:

首先将所有奶牛按照c升序排序,那么最终答案一定包含c最小的前k个奶牛(如若不然,设前k个奶牛中,第i头奶牛没有在最终方案中,而最终方案中一定有一头用了优惠券的奶牛jcic大,于是我们不买j,选择用优惠券买i,显然用的钱更少)

开三个优先队列(都是小根堆)q,q2,q3,分别表示还没有购买的奶牛的原价,还没有购买的奶牛的优惠价以及已经购买了的且使用了优惠券的奶牛的原价减去优惠价

我们认为已经买了的奶牛是一定不会不买的,我们只需要考虑优惠券的转移;现在我们想要多买一头奶牛,如果我们用原价买这头奶牛,就选择q1的堆顶,如果我们要用优惠券买这个奶牛,那么优惠券就要发生转移,于是考虑q2的堆顶加上q3的堆顶,并将新的用了优惠券的奶牛的原价减优惠价加入q3,所以比较q1的堆顶和q2的堆顶加上q3的堆顶即可;然后重复以上过程直到钱不够用了

以上只是直觉,缺少严格证明,下面证明:

假设我们已经买了的奶牛集合A在最终方案中一定都会买(这里利用数学归纳法证明,Base是成立的,因为我们最开始是按照c升序排序的,已经说明了前k个奶牛一定会买的),并且对于已经买了的奶牛,优惠券的分配是最优的,那么如果我们想要多买一头奶牛,下面只分析q1的堆顶小于q2的堆顶加上q3的堆顶(反之同理分析):设q1堆顶代表的奶牛是i,如果我们最终方案中不买i,那么对于最终方案中不属于A的奶牛,如果都是以原价买的,那么显然随便舍弃一头奶牛买i都更优,如果存在奶牛j用了优惠券,那么这个优惠券一定是从A中用了优惠券的奶牛身上转移过来的,然而我们有q1的堆顶小于q2的堆顶加上q3的堆顶,q2的堆顶加上q3的堆顶小于将优惠券转移到j上所产生的价格,所以q1的堆顶小价格于将优惠券转移到j上所产生的价格,于是我们将“将优惠券转移到j上”变成“买i并且不转移优惠券”显然是一种更优的方案,所以i是一定要买的。并且此时优惠券的分配也是最优的

update 2024.7.22

反悔贪心小结反悔贪心

update 2025.1.8

想到了按c升序排序并且前k个奶牛一定会买,但是剩下这个太难了

posted @   最爱丁珰  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示