Smart Phone
Editorial written by Ekansh Majumder.
The price can be any value in the range , and there are up to customers. Brute-forcing this by iterating over all possible prices will not pass the time constraints.
Observation 1
Notice that the answer can only be one of the values in the input array. This is because the number of buyers does not change if you choose any value in between two elements in the array.
For example, take an array of size :
- If we set the phone price to , only the third user can buy the phone, and anyone before it cannot.
- If we set the price to anything in the range , notice that the set of buyers remains same, but our profit per unit only decreases.
- The next change in the set of buyers happens when we set the price down to ; now both the second and third users can buy the phone.
- There is no change again for any price in the range .
Thus, we have reduced the search space from candidate prices to only the values present in the input array.
Subtask 1
In this subtask, . There are at most 5000 customers to check.
This is the brute-force solution, as we can afford an approach.
Here is a code snippet for the same:
for (int i = 0; i < n; i++) {
int count = 0;
for (int j = 0; j < n; j++) {
if (budgets[j] >= budgets[i]) {
count++;
}
}
int curr = budgets[i] * count; // Current profit
ans = max(max_revenue, curr);
}We iterate through the budgets array and set the candidate price to . We then loop through all from to to find the number of customers who can afford the phone. Finally, we calculate the profit and maintain the maximum over all .
The time complexity of this solution is as we use another for loop inside our initial for loop to iterate through all pairs.
Observation 2
We are currently taking time to check the number of buyers for each price. Let’s try to notice a pattern in this array. To begin with, let’s sort it in non-increasing order (we could’ve also chosen non-decreasing):
- When we set the price to , we have buyers.
- When we set the price to , we have buyers.
- When we set the price to , we have buyers.
This pattern continues as long as the array remains sorted. If the array is sorted in non-increasing order then, for each budget, everyone to the left of that budget (along with the current customer) can buy. Therefore, the number of buyers is simply the 1-based index of the budget, or with 0-based indexing.
Subtask 2
In this subtask, . We will try to optimize our current approach to get an solution.
Using observation 2, we can sort the array in non-increasing order. For each budget, the profit we can achieve is:
sort(budgets.rbegin(), budgets.rend());
int ans = 0;
for (int i = 0; i < n; i++) {
int profit = budgets[i] * (i + 1);
ans = max(ans, profit);
}Let’s analyze the time complexity of this snippet:
- Sorting the array takes .
- Iterating through the array takes .
This gives an overall time complexity of:
The time complexity of this solution is as sorting the array takes , and iterating through the array takes .
Implementation
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<long long> budgets(n);
for (int i = 0; i < n; i++) {
cin >> budgets[i];
}
sort(budgets.rbegin(), budgets.rend());
long long ans = 0;
for (int i = 0; i < n; i++) {
long long profit = budgets[i] * (i + 1);
ans = max(ans, profit);
}
cout << ans << endl;
}