ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Powerful Discount Tickets(贪心,数学)

2022-06-24 15:02:08  阅读:142  来源: 互联网

标签:Tickets lfloor 优惠券 frac Powerful rfloor Discount 物品 include


题意

有\(N\)件物品,每件物品价格为\(A_i\)元。

你现在有\(K\)张优惠券。对于一个价格为\(X\)的物品,如果你使用\(y\)张优惠券,则你需要花费\(\lfloor \frac{X}{2^y} \rfloor\)元。

求购买所有物品需要花费多少元钱?

题目链接:https://atcoder.jp/contests/abc141/tasks/abc141_d

数据范围

\(1 \leq N, K \leq 10^5\)

思路

我们可以观察一下\(\lfloor \frac{X}{2^0} \rfloor\),\(\lfloor \frac{X}{2^1} \rfloor\),\(\lfloor \frac{X}{2^2} \rfloor\),\(\dots\)的结果。我们可以发现变化幅度是减小的,也就是将优惠券用在价格更高的物品上更好。

因此,我们可以考虑每次使用一张优惠券,用在当前价格最高的物品上,然后该物品价格除以\(2\)。这个过程可以使用优先队列进行维护。

这个做法为什么是正确的呢?因为这里有一条性质:对于任意正整数\(X, b_1, b_2\),有\(\lfloor \frac{\lfloor \frac{X}{b_1} \rfloor}{b_2} \rfloor = \lfloor \frac{X}{b_1 b_2} \rfloor\)。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

typedef long long ll;

int n, k;

int main()
{
    priority_queue<int> que;
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i ++) {
        int x;
        scanf("%d", &x);
        que.push(x);
    }
    while(k --) {
        int t = que.top();
        que.pop();
        que.push(t / 2);
    }
    ll ans = 0;
    while(que.size()) {
        int t = que.top();
        ans += (ll)t;
        que.pop();
    }
    printf("%lld\n", ans);
    return 0;
}

标签:Tickets,lfloor,优惠券,frac,Powerful,rfloor,Discount,物品,include
来源: https://www.cnblogs.com/miraclepbc/p/16408853.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有