You are given a 0-indexedm * n integer matrix values, representing the values of m * n different items in m different shops. Each shop has
n items where the jth item in the ith shop has a value of
values[i][j]. Additionally, the items in the ith shop are sorted in non-increasing order of value. That is, values[i][j] >= values[i][j + 1] for all
0 <= j < n - 1.
On each day, you would like to buy a single item from one of the shops.
Specifically, On the dth day you can:
Pick any shop i.
Buy the rightmost available item j for the price of values[i][j] * d. That is, find the greatest index j such that item j was never bought before, and buy it for the price of values[i][j] * d.
Note that all items are pairwise different. For example, if you have bought item 0 from shop 1, you can still buy item 0 from any other shop.
Return _themaximum amount of money that can be spent on buying all _ m * nproducts.
Input: values =[[8,5,2],[6,4,1],[9,7,3]]Output: 285Explanation: On the first day, we buy product 2 from shop 1for a price of values[1][2]*1=1.On the second day, we buy product 2 from shop 0for a price of values[0][2]*2=4.On the third day, we buy product 2 from shop 2for a price of values[2][2]*3=9.On the fourth day, we buy product 1 from shop 1for a price of values[1][1]*4=16.On the fifth day, we buy product 1 from shop 0for a price of values[0][1]*5=25.On the sixth day, we buy product 0 from shop 1for a price of values[1][0]*6=36.On the seventh day, we buy product 1 from shop 2for a price of values[2][1]*7=49.On the eighth day, we buy product 0 from shop 0for a price of values[0][0]*8=64.On the ninth day, we buy product 0 from shop 2for a price of values[2][0]*9=81.Hence, our total spending is equal to 285.It can be shown that 285is the maximum amount of money that can be spent buying all m * n products.
Input: values =[[10,8,6,4,2],[9,7,5,3,2]]Output: 386Explanation: On the first day, we buy product 4 from shop 0for a price of values[0][4]*1=2.On the second day, we buy product 4 from shop 1for a price of values[1][4]*2=4.On the third day, we buy product 3 from shop 1for a price of values[1][3]*3=9.On the fourth day, we buy product 3 from shop 0for a price of values[0][3]*4=16.On the fifth day, we buy product 2 from shop 1for a price of values[1][2]*5=25.On the sixth day, we buy product 2 from shop 0for a price of values[0][2]*6=36.On the seventh day, we buy product 1 from shop 1for a price of values[1][1]*7=49.On the eighth day, we buy product 1 from shop 0for a price of values[0][1]*8=64On the ninth day, we buy product 0 from shop 1for a price of values[1][0]*9=81.On the tenth day, we buy product 0 from shop 0for a price of values[0][0]*10=100.Hence, our total spending is equal to 386.It can be shown that 386is the maximum amount of money that can be spent buying all m * n products.
To maximize the total spending, we want to buy the cheapest available item on the earliest day (when the multiplier is smallest), and the most expensive items on the latest days (when the multiplier is largest). This is achieved by always picking the rightmost (smallest) item from any shop each day, using a min-heap to efficiently select the minimum.
classSolution {
public:longlong maxSpending(vector<vector<int>>& values) {
int m = values.size(), n = values[0].size();
using T = tuple<int, int, int>;
priority_queue<T, vector<T>, greater<T>> pq;
for (int i =0; i < m; ++i)
pq.emplace(values[i][n-1], i, n-1);
longlong ans =0;
for (int d =1; d <= m * n; ++d) {
auto [v, i, j] = pq.top(); pq.pop();
ans +=1LL* v * d;
if (j >0) pq.emplace(values[i][j-1], i, j-1);
}
return ans;
}
};
import java.util.*;
classSolution {
publiclongmaxSpending(int[][] values) {
int m = values.length, n = values[0].length;
PriorityQueue<int[]> pq =new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
for (int i = 0; i < m; ++i)
pq.offer(newint[]{values[i][n-1], i, n-1});
long ans = 0;
for (int d = 1; d <= m * n; ++d) {
int[] x = pq.poll();
ans += 1L * x[0]* d;
if (x[2]> 0) pq.offer(newint[]{values[x[1]][x[2]-1], x[1], x[2]-1});
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.PriorityQueue
classSolution {
funmaxSpending(values: Array<IntArray>): Long {
val m = values.size; val n = values[0].size
val pq = PriorityQueue(compareBy<Triple<Int, Int, Int>> { it.first })
for (i in0 until m) pq.add(Triple(values[i][n-1], i, n-1))
var ans = 0Lfor (d in1..(m*n)) {
val(v, i, j) = pq.poll()
ans += v.toLong() * d
if (j > 0) pq.add(Triple(values[i][j-1], i, j-1))
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
import heapq
classSolution:
defmaxSpending(self, values: list[list[int]]) -> int:
m, n = len(values), len(values[0])
pq = [(values[i][n-1], i, n-1) for i in range(m)]
heapq.heapify(pq)
ans =0for d in range(1, m*n+1):
v, i, j = heapq.heappop(pq)
ans += v * d
if j >0:
heapq.heappush(pq, (values[i][j-1], i, j-1))
return ans
use std::collections::BinaryHeap;
use std::cmp::Reverse;
impl Solution {
pubfnmax_spending(values: Vec<Vec<i32>>) -> i64 {
let m = values.len();
let n = values[0].len();
letmut heap = BinaryHeap::new();
for i in0..m {
heap.push(Reverse((values[i][n-1], i, n-1)));
}
letmut ans =0i64;
for d in1..=m*n {
let Reverse((v, i, j)) = heap.pop().unwrap();
ans += v asi64* d asi64;
if j >0 {
heap.push(Reverse((values[i][j-1], i, j-1)));
}
}
ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
maxSpending(values: number[][]):number {
constm=values.length, n=values[0].length;
constpq: [number, number, number][] = [];
for (leti=0; i<m; ++i) pq.push([values[i][n-1], i, n-1]);
pq.sort((a, b) =>a[0] -b[0]);
letans=0;
for (letd=1; d<=m*n; ++d) {
pq.sort((a, b) =>a[0] -b[0]);
const [v, i, j] =pq.shift()!;
ans+=v*d;
if (j>0) pq.push([values[i][j-1], i, j-1]);
}
returnans;
}
}
⏰ Time complexity: O(mn log m), where m is the number of shops and n is the number of items per shop. Each heap operation is O(log m) and there are mn operations.
🧺 Space complexity: O(m), for the heap storing one item per shop.