You have an inventory of different colored balls, and there is a customer that wants orders balls of any color.
The customer weirdly values the colored balls. Each colored ball’s value is the number of balls **of that color **you currently have in your inventory.
For example, if you own 6 yellow balls, the customer would pay 6 for the first yellow ball. After the transaction, there are only 5 yellow balls left, so the next yellow ball is then valued at 5 (i.e., the value of the balls decreases as you sell more to the customer).
You are given an integer array, inventory, where inventory[i] represents the number of balls of the ith color that you initially own. You are also given an integer orders, which represents the total number of balls that the customer wants. You can sell the balls in any order.
Return _themaximum total value that you can attain after selling _orderscolored balls. As the answer may be too large, return it modulo109 + 7.

Input: inventory =[2,5], orders =4Output: 14Explanation: Sell the 1st color 1time(2) and the 2nd color 3times(5+4+3).The maximum total value is2+5+4+3=14.
Input: inventory =[3,5], orders =6Output: 19Explanation: Sell the 1st color 2times(3+2) and the 2nd color 4times(5+4+3+2).The maximum total value is3+2+5+4+3+2=19.
To maximize the total value, always sell the highest-valued balls first. As you sell a ball of a color, its value decreases by 1. This is a greedy problem: always pick the color with the most balls left. We can use a max-heap or sort the inventory and process in batches.
#include<vector>#include<algorithm>usingnamespace std;
classSolution {
public:int maxProfit(vector<int>& inventory, int orders) {
constint MOD =1e9+7;
sort(inventory.rbegin(), inventory.rend());
inventory.push_back(0);
long res =0;
int n = inventory.size();
for (int i =0, k =1; orders >0&& i < n-1; ++i, ++k) {
if (inventory[i] > inventory[i+1]) {
long cnt = (long)(inventory[i] - inventory[i+1]) * k;
long take = min((long)orders, cnt);
long full = take / k, rem = take % k;
res = (res + k * (inventory[i] + inventory[i] - full +1) * full /2) % MOD;
res = (res + rem * (inventory[i] - full)) % MOD;
orders -= take;
}
}
return res;
}
};
import java.util.*;
classSolution {
publicintmaxProfit(int[] inventory, int orders) {
finalint MOD = 1_000_000_007;
Arrays.sort(inventory);
int n = inventory.length;
long res = 0;
int k = 1;
for (int i = n-1; orders > 0; --i, ++k) {
int cur = inventory[i], next = i > 0 ? inventory[i-1] : 0;
if (cur > next) {
long cnt = (long)(cur - next) * k;
long take = Math.min(orders, (int)cnt);
long full = take / k, rem = take % k;
res = (res + k * (cur + cur - full + 1) * full / 2) % MOD;
res = (res + rem * (cur - full)) % MOD;
orders -= take;
}
}
return (int)res;
}
}
classSolution {
funmaxProfit(inventory: IntArray, orders: Int): Int {
val MOD = 1_000_000_007
inventory.sortDescending()
val inv = inventory + 0var res = 0Lvar k = 1var o = orders
for (i in0 until inv.size-1) {
if (inv[i] > inv[i+1]) {
val cnt = (inv[i] - inv[i+1]) * k
val take = minOf(o, cnt)
val full = take / k
val rem = take % k
res = (res + k * (inv[i] + inv[i] - full + 1) * full / 2) % MOD
res = (res + rem * (inv[i] - full)) % MOD
o -= take
}
k++if (o ==0) break }
return res.toInt()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
defmaxProfit(inventory, orders):
MOD =10**9+7 inventory.sort(reverse=True)
inventory.append(0)
res =0 k =1for i in range(len(inventory)-1):
if inventory[i] > inventory[i+1]:
cnt = (inventory[i] - inventory[i+1]) * k
take = min(orders, cnt)
full, rem = divmod(take, k)
res = (res + k * (inventory[i] + inventory[i] - full +1) * full //2) % MOD
res = (res + rem * (inventory[i] - full)) % MOD
orders -= take
if orders ==0:
break k +=1return res
pubfnmax_profit(mut inventory: Vec<i32>, mut orders: i32) -> i32 {
constMOD: i64=1_000_000_007;
inventory.sort_unstable_by(|a, b| b.cmp(a));
inventory.push(0);
letmut res =0i64;
letmut k =1;
for i in0..inventory.len()-1 {
if inventory[i] > inventory[i+1] {
let cnt = (inventory[i] - inventory[i+1]) asi64* k;
let take = (orders asi64).min(cnt);
let full = take / k;
let rem = take % k;
res = (res + k * (inventory[i] asi64+ inventory[i] asi64- full +1) * full /2) %MOD;
res = (res + rem * (inventory[i] asi64- full)) %MOD;
orders -= take asi32;
if orders ==0 { break; }
}
k +=1;
}
res asi32}