给你一个下标从 0 开始大小为
m * n
的整数矩阵values
,表示m
个不同商店里m * n
件不同的物品。每个商店有n
件物品,第i
个商店的第j
件物品的价值为values[i][j]
。除此以外,第i
个商店的物品已经按照价值非递增排好序了,也就是说对于所有0 <= j < n - 1
都有values[i][j] >= values[i][j + 1]
。每一天,你可以在一个商店里购买一件物品。具体来说,在第
d
天,你可以:
选择商店
i
。购买数组中最右边的物品
j
,开销为values[i][j] * d
。换句话说,选择该商店中还没购买过的物品中最大的下标j
,并且花费values[i][j] * d
去购买。注意,所有物品都视为不同的物品。比方说如果你已经从商店
1
购买了物品0
,你还可以在别的商店里购买其他商店的物品0
。请你返回购买所有
m * n
件物品需要的 最大开销 。
难点在于开销通过values[i][j]*d计算,考虑排序不等式:
https://baike.baidu.com/item/%E6%8E%92%E5%BA%8F%E4%B8%8D%E7%AD%89%E5%BC%8F/7775728
因此考虑贪心策略:每一次取当前可取的最小值
因为所有物品都可以取完,不存在局部最优解非全局最优解的情况。
Code:
class Solution {
public:
long long maxSpending(std::vector<std::vector<int>>& values) {
auto cp=[&](const std::pair<int,int>&l,const std::pair<int,int>&r){
return l.first>r.first;
};
std::priority_queue<std::pair<int,int>,std::vector<std::pair<int,int>>,decltype(cp)> priorityQueue(cp);
for (int i = 0; i < values.size(); ++i) {
priorityQueue.emplace(values[i].back(), i);
values[i].pop_back();
}
long long day=1;
long long max=0;
while (!priorityQueue.empty()){
auto[a,b]=priorityQueue.top();
priorityQueue.pop();
max+=a*day;
day++;
if (!values[b].empty()){
priorityQueue.emplace(values[b].back(),b);
values[b].pop_back();
}
}
return max;
}
};
评论区