[H排序] lc2931. 购买物品的最大开销(排序+最小堆+脑筋急转弯)

1. 题目来源

链接:2931. 购买物品的最大开销

题单:

  • 待补充

2. 题目解析

思路一: 排序

  • 第一种排序的想法没有想到。
  • 一定可以完全按照降序的方式取完所有数据。即便两次取在了同一行,那也说明第二次取的该行数据也是比其他的末尾数据还要小的。也是合法写法。
  • 理解这个后,直接将二维数组一维化,然后排序就行了。

思路二: 最小堆

  • 这个就很容易理解了,类似与多路归并一样,拿最小堆维护当前的最小值即可。
  • 也是直接采用这个方法写的。

  • 时间复杂度 O ( n log ⁡ ( n ) ) O(n \log(n)) O(nlog(n))
  • 空间复杂度 O ( n ) O(n) O(n)

方法一:排序

class Solution {
public:
    long long maxSpending(vector<vector<int>>& values) {
        typedef long long LL;
        LL res = 0;
        vector<int> f;
        for (auto vv : values) for (auto v : vv) f.push_back(v);
        sort(f.begin(), f.end());


        for (int i = 1; i <= f.size(); i ++ ) res += 1ll * i * f[i - 1];
        return res;
    }
};

方法二:最小堆

class Solution {
public:
    long long maxSpending(vector<vector<int>>& values) {
        typedef long long LL;
        typedef pair<int, int> PII;
        #define x first
        #define y second
        priority_queue<PII, vector<PII>, greater<PII>> q;
        int n = values.size(), m = values[0].size();
        
        vector<int> idx(n, m);
        for (int i = 0; i < n; i ++ ) q.push({values[i][m - 1], i});

        LL res = 0;
        for (int i = 1; i <= n * m; i ++ ) {
            auto t = q.top(); q.pop();
            res += 1ll * i * t.x;
            if (idx[t.y] > 1) {
                idx[t.y] -- ;
                q.push({values[t.y][idx[t.y] - 1], t.y});
            }
        }

        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值