I got asked this on hacker rank and I haven't figured out a solution that didn't run out of allotted time. I used php and allotted time was 9 seconds...
The idea is there are "ticket stalls" with a certain number of tickets, say 9. Any ticket they sell is priced at the number of tickets that remain, so first ticket would be $9, second $8 etc...
You're given two lines of data, say:
2 4
1 5
The first row contains two numbers:
The second line contains a list of how many tickets each stall has initially, so in this case stall 1 has 1 ticket, stall 2 has 5 tickets.
The problem: what is the maximum amount of money you can make selling the given number of tickets?
In this case, you sell four tickets from stall two for a price of 5 + 4 + 3 + 2 = $14
So how do you solve it. I figured out two ways, both of which ran out of time
Load the stall numbers (second line) into an array. Go through that array N times (the number of tickets to sell) picking the largest number out, adding it on to an aggregator, decreasing that number. Then you have the total in the aggregator.
Load the stall numbers into an array. Sort the array. Go backwards through the array and as you do: store that number (current), add it to the aggregator, go to the next value. If it is the same (current), then add it to aggregator, subtract 1 from it, keep going. If it is different, go back to the end of the array and start again. Do that N times (the internal loop, not the external one).
The problem: neither one worked.
Can anyone think of a better solution?
There's also an obvious way to improve this by multiplying out by MIN(count in highest stall, remaining tickets to be sold).
NOTE: in order for this to perform well, your implementation language must have true arrays (i.e., constant access time, regardless of the index). I do not know PHP, but some languages (JS?) use sequential lists to mimic arrays, but do not have the same performance.
Below is the Java implementation of the mentioned approach (read through comments to understand better):
int[] stalls = new int[] { 4, 7, 1, 4, 8, 8 };
int t = 4;
Arrays.sort(stalls);
int tickets = stalls[stalls.length - 1];
int[] dp = new int[tickets + 1];
for (int i = 0; i < stalls.length; i++) {
dp[stalls[i]]++;
}
int total = 0;
int i = dp.length - 1;
while (t > 0) {
if (dp[i] > 0) {
total += i;
t--;
dp[i]--;
dp[i - 1]++;
} else {
i--;
}
}
System.out.println(total);