Maximize the profit after selling the tickets | Set 2 (For elements in range [1, 10^6])
Last Updated :
19 Aug, 2021
Given an array, arr[] of size N where arr[i] represents the number of tickets, the ith seller has and a positive integer K. The price of a ticket is the number of tickets remaining with the ticket seller. They can sell a total of K tickets. Find the maximum amount they can earn by selling K tickets. Give the answer modulo 109 + 7.
Examples:
Input: seats[] = {2, 1, 1}, K= 3
Output: 4
Explanation: Consider 0 based indexing. For first two turns the 2nd seller sells. For the third turn either 0th or 2nd seller can sell. So the total becomes 6 + 5 + 4 = 15.
Input: seats[] = {2, 3, 4, 5, 1}, K = 6
Output: 22
Approach : The naive approach and efficient approach is discussed in this article.
The approaches mentioned in the article can be optimized further by observing that since all the elements are less than or equal to 10^6, therefore, we can store the frequency of all the elements in an array A[]. Follow the steps below to solve the problem:
- Create an array A[] that stores the frequency of each element of the array arr[].
- Iterate in the range [0, N-1] using the variable i and increment the value of A[arr[i]] by 1.
- Initialize a variable, say j that keeps the track of the position of the array elements.
- Iterate in the range [0, 1000000] using the variable i and perform the following steps:
- While A[i] != 0, modify the value of arr[j] as i and decrement the value of A[i] by 1.
- Initialize two variable, say i as N-1 and j as N-2.
- Initialize a variable, say ans as 0.
- Iterate while k>0 and j>=0 and perform the following steps:
- If arr[i] > arr[j],
- Then add min(K, i-j)*arr[i] to the answer.
- Decrement the value of K by i-j and decrement the value of arr[i] by 1.
- Otherwise,
- Decrement the value of j while arr[j] = arr[i].
- Then add min(K, i-j)*arr[i] to the answer ans.
- Decrement the value of K by i-j and decrement the value of arr[i] by 1.
- Iterate while K>0 and arr[i]>0 and perform the following steps:
- Then add min(K, N)*arr[i] to the answer ans.
- Decrement the value of K by N and decrease the value of arr[i] by 1.
- After performing the above steps, print the value of ans as the answer.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxAmount( int n, int k, int arr[])
{
int A[1000001] = { 0 };
for ( int i = 0; i < n; i++) {
A[arr[i]]++;
}
int j = 0;
for ( int i = 0; i < 1000001; i++) {
while (A[i] != 0) {
arr[j++] = i;
A[i]--;
}
}
long long int ans = 0;
int mod = 1e9 + 7;
int i = n - 1;
j = n - 2;
while (k > 0 && j >= 0) {
if (arr[i] > arr[j]) {
ans = ans + min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
else {
while (j >= 0 && arr[j] == arr[i])
j--;
if (j < 0)
break ;
ans = ans + min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
}
while (k > 0 && arr[i] != 0) {
ans = ans + min(n, k) * arr[i];
k -= n;
arr[i]--;
}
ans = ans % mod;
int x = ans;
return x;
}
int main()
{
int n = 5;
int k = 3;
int arr[n] = { 4, 3, 6, 2, 4 };
int ans = maxAmount(n, k, arr);
cout << ans;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int maxAmount( int n, int k, int arr[])
{
int A[] = new int [ 1000001 ];
for ( int i = 0 ; i < n; i++) {
A[arr[i]]++;
}
int j = 0 ;
for ( int i = 0 ; i < 1000001 ; i++) {
while (A[i] != 0 ) {
arr[j++] = i;
A[i]--;
}
}
int ans = 0 ;
int mod = ( int ) (1e9 + 7 );
int i = n - 1 ;
j = n - 2 ;
while (k > 0 && j >= 0 ) {
if (arr[i] > arr[j]) {
ans = ans + Math.min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
else {
while (j >= 0 && arr[j] == arr[i])
j--;
if (j < 0 )
break ;
ans = ans + Math.min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
}
while (k > 0 && arr[i] != 0 ) {
ans = ans + Math.min(n, k) * arr[i];
k -= n;
arr[i]--;
}
ans = ans % mod;
int x = ans;
return x;
}
public static void main(String[] args)
{
int n = 5 ;
int k = 3 ;
int arr[] = { 4 , 3 , 6 , 2 , 4 };
int ans = maxAmount(n, k, arr);
System.out.print(ans);
}
}
|
Python3
def maxAmount(n, k, arr):
A = [ 0 for i in range ( 1000001 )]
for i in range (n):
A[arr[i]] + = 1
j = 0
for j in range ( 1000001 ):
while (A[i] ! = 0 ):
arr[j] = i;
j + = 1
A[i] - = 1
ans = 6
mod = 1000000007
i = n - 1
j = n - 2
while (k > 0 and j > = 0 ):
if (arr[i] > arr[j]):
ans = ans + min (k, (i - j)) * arr[i]
k = k - (i - j)
arr[i] - = 1
else :
while (j > = 0 and arr[j] = = arr[i]):
j - = 1
if (j < 0 ):
break
ans = ans + min (k, (i - j)) * arr[i]
k = k - (i - j)
arr[i] - = 1
while (k > 0 and arr[i] ! = 0 ):
ans = ans + min (n, k) * arr[i]
k - = n
arr[i] - = 1
ans = ans % mod
x = ans
return x
if __name__ = = '__main__' :
n = 5
k = 3
arr = [ 4 , 3 , 6 , 2 , 4 ]
ans = maxAmount(n, k, arr)
print (ans)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int maxAmount( int n, int k, int []arr)
{
int i;
int []A = new int [1000001];
Array.Clear(A,0,1000001);
for (i = 0; i < n; i++) {
A[arr[i]]++;
}
int j = 0;
for (i = 0; i < 1000001; i++) {
while (A[i] != 0) {
arr[j++] = i;
A[i]--;
}
}
int ans = 0;
int mod = 1000000007;
i = n - 1;
j = n - 2;
while (k > 0 && j >= 0) {
if (arr[i] > arr[j]) {
ans = ans + Math.Min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
else {
while (j >= 0 && arr[j] == arr[i])
j--;
if (j < 0)
break ;
ans = ans + Math.Min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
}
while (k > 0 && arr[i] != 0) {
ans = ans + Math.Min(n, k) * arr[i];
k -= n;
arr[i]--;
}
ans = ans % mod;
int x = ans;
return x;
}
public static void Main()
{
int n = 5;
int k = 3;
int []arr = { 4, 3, 6, 2, 4 };
int ans = maxAmount(n, k, arr);
Console.Write(ans);
}
}
|
Javascript
<script>
function maxAmount(n, k, arr)
{
let A = new Array(1000001).fill(0);
for (let i = 0; i < n; i++)
{
A[arr[i]]++;
}
let j = 0;
for (let i = 0; i < 1000001; i++) {
while (A[i] != 0) {
arr[j++] = i;
A[i]--;
}
}
let ans = 0;
let mod = 1e9 + 7;
let i = n - 1;
j = n - 2;
while (k > 0 && j >= 0) {
if (arr[i] > arr[j]) {
ans = ans + Math.min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
else {
while (j >= 0 && arr[j] == arr[i])
j--;
if (j < 0)
break ;
ans = ans + Math.min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
}
while (k > 0 && arr[i] != 0) {
ans = ans + Math.min(n, k) * arr[i];
k -= n;
arr[i]--;
}
ans = ans % mod;
let x = ans;
return x;
}
let n = 5;
let k = 3;
let arr = [4, 3, 6, 2, 4];
let ans = maxAmount(n, k, arr);
document.write(ans);
</script>
|
Time Complexity:O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...