Strange Birthday Party

这篇博客探讨了一个关于生日派对礼物分配的问题。题目要求根据朋友手中的数字,选择不超过该数字序号的商品或者相应金额,以最小化总花费。博主首先因理解错误而走了弯路,然后重新理解题意并提出了正确的解决方案:将商品按价值升序排列,朋友数字降序排列,优先赠送小价值商品,从而达到总花费最小。博主通过排序和双指针算法实现了这一策略,并给出了C++代码实现。
摘要由CSDN通过智能技术生成

Strange Birthday Party
看题不仔细,做题两行泪。
一开始以为给每个朋友的礼物是小于等于手上数字的商品序号或等量钱。虽然每件商品都只有一件,但都可选的价值最小的商品的钱就行。看案例解释没看懂,也没回去看题。

正确题意:给每个人小于等于手上数字序号的任意一件商品(每个商品用一次),或者给手上序号对应商品的钱

做题思路:商品价值已经是按非降序排列。朋友手上的数字没有规律,将这个数组按非升序排列,朋友对于每一件商品,如果有一个朋友的数字≥该商品的序号并且还没给他送礼物,那么给他送这件商品比送钱更优。因此要送哪些商品是已经确定的。当钱送的最少时,用总花费就最少。
商品价值按升序排列,因此朋友的数字越小,送的钱越少。
将朋友的数字按降序排列,先把所有应该送的小价值商品送完,剩下的是朋友全送钱,此时送的钱最少。即总花费最少。

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

using namespace std;

const int N = 300010;

 int f[N], p[N];
 bool st[N];

 int main() {
    int n, m, t;
    scanf("%d", &t);
    while (t --) {

        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i ++)    scanf("%d", &f[i]);
        for (int i = 1; i <= m; i ++)    scanf("%d", &p[i]);

        long long ans = 0, ch = 0;
        sort(f + 1, f + n + 1, greater<int>());
        for (int i = 1; i <= n; i ++) {
            if (++ ch < m && p[f[i]] >= p[ch])ans += p[ch];
            else ans += p[f[i]];

        }

        printf("%lld\n", ans);
    }
    return 0;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值