给定一个大小为N的数组arr[] ,其中 arr[i] 表示票数、第 i 个卖家拥有的票数和一个正整数K 。门票的价格是售票员剩余的门票数量。他们总共可以卖出K张票。找出他们通过出售 K 票可以获得的最大金额。以10 9 + 7 为模数给出答案。
例子:
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
方法:本文讨论了幼稚的方法和有效的方法。
文章中提到的方法可以通过观察进一步优化,因为所有元素都小于或等于 10^6 ,因此,我们可以将所有元素的频率存储在数组 A[] 中。请按照以下步骤解决问题:
- 创建一个数组A[] ,用于存储数组arr[]的每个元素的频率。
- 使用变量i在范围[0, N-1] 中迭代并将A[arr[i]]的值增加1 。
- 初始化一个变量,比如j ,它跟踪数组元素的位置。
- 使用变量i在范围[0, 1000000] 中迭代并执行以下步骤:
- 当A[i] != 0 时,将arr[j]的值修改为 i 并将A[i]的值减1 。
- 初始化两个变量,假设i为N-1 , j为N-2 。
- 初始化一个变量,比如ans为0 。
- 在k>0和j>=0 时迭代并执行以下步骤:
- 如果arr[i] > arr[j] ,
- 然后将min(K, ij)*arr[i] 添加到答案中。
- 将K的值减少ij并将 arr[i] 的值减少 1。
- 除此以外,
- 在arr[j] = arr[i] 时递减j的值。
- 然后将min(K, ij)*arr[i] 添加到答案ans 中。
- 将K的值减少ij并将 arr[i] 的值减少 1。
- 如果arr[i] > arr[j] ,
- 迭代而K>0和arr[i]>0并执行以下步骤:
- 然后将min(K, N)*arr[i] 添加到答案ans 中。
- 将K的值减少N,并将 arr[i] 的值减少 1。
- 执行完上述步骤后,打印ans的值作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find maximum profit
// after selling K tickets
int maxAmount(int n, int k, int arr[])
{
// Frequency array to store freq
// of every element of the array
int A[1000001] = { 0 };
for (int i = 0; i < n; i++) {
A[arr[i]]++;
}
int j = 0;
// Modify the arr[] so that the
// array is sorted in O(N)
for (int i = 0; i < 1000001; i++) {
while (A[i] != 0) {
arr[j++] = i;
A[i]--;
}
}
// Variable to store answer
long long int ans = 0;
int mod = 1e9 + 7;
int i = n - 1;
j = n - 2;
// Traverse the array while K>0
// and j>=0
while (k > 0 && j >= 0) {
// If arr[i] > arr[j] then
// ticket can be brought from
// counter [j+1, N]
if (arr[i] > arr[j]) {
ans = ans + min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
else {
// If arr[j] == arr[i] decrement j until
// arr[j] != arr[i]
while (j >= 0 && arr[j] == arr[i])
j--;
if (j < 0)
break;
// Sell tickets from counter [j+1, N]
ans = ans + min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
}
// All elements of array are equal
// Send tickets from each counter 1
// time until K > 0.
while (k > 0 && arr[i] != 0) {
ans = ans + min(n, k) * arr[i];
k -= n;
arr[i]--;
}
ans = ans % mod;
// Converting answer from long long
// to int
int x = ans;
return x;
}
// Driver Code
int main()
{
// Given Input
int n = 5;
int k = 3;
int arr[n] = { 4, 3, 6, 2, 4 };
// Function Call
int ans = maxAmount(n, k, arr);
cout << ans;
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find maximum profit
// after selling K tickets
static int maxAmount(int n, int k, int arr[])
{
// Frequency array to store freq
// of every element of the array
int A[] = new int[1000001];
for (int i = 0; i < n; i++) {
A[arr[i]]++;
}
int j = 0;
// Modify the arr[] so that the
// array is sorted in O(N)
for (int i = 0; i < 1000001; i++) {
while (A[i] != 0) {
arr[j++] = i;
A[i]--;
}
}
// Variable to store answer
int ans = 0;
int mod = (int) (1e9 + 7);
int i = n - 1;
j = n - 2;
// Traverse the array while K>0
// and j>=0
while (k > 0 && j >= 0) {
// If arr[i] > arr[j] then
// ticket can be brought from
// counter [j+1, N]
if (arr[i] > arr[j]) {
ans = ans + Math.min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
else {
// If arr[j] == arr[i] decrement j until
// arr[j] != arr[i]
while (j >= 0 && arr[j] == arr[i])
j--;
if (j < 0)
break;
// Sell tickets from counter [j+1, N]
ans = ans + Math.min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
}
// All elements of array are equal
// Send tickets from each counter 1
// time until K > 0.
while (k > 0 && arr[i] != 0) {
ans = ans + Math.min(n, k) * arr[i];
k -= n;
arr[i]--;
}
ans = ans % mod;
// Converting answer from long long
// to int
int x = ans;
return x;
}
// Driver Code
public static void main(String[] args)
{
// Given Input
int n = 5;
int k = 3;
int arr[] = { 4, 3, 6, 2, 4 };
// Function Call
int ans = maxAmount(n, k, arr);
System.out.print(ans);
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
# Function to find maximum profit
# after selling K tickets
def maxAmount(n, k, arr):
# Frequency array to store freq
# of every element of the array
A = [0 for i in range(1000001)]
for i in range(n):
A[arr[i]] += 1
j = 0
# Modify the arr[] so that the
# array is sorted in O(N)
for j in range(1000001):
while(A[i] != 0):
arr[j] = i;
j += 1
A[i] -= 1
# Variable to store answer
ans = 6
mod = 1000000007
i = n - 1
j = n - 2
# Traverse the array while K>0
# and j>=0
while (k > 0 and j >= 0):
# If arr[i] > arr[j] then
# ticket can be brought from
# counter [j+1, N]
if (arr[i] > arr[j]):
ans = ans + min(k, (i - j)) * arr[i]
k = k - (i - j)
arr[i] -= 1
else:
# If arr[j] == arr[i] decrement j until
# arr[j] != arr[i]
while (j >= 0 and arr[j] == arr[i]):
j -= 1
if (j < 0):
break
# Sell tickets from counter [j+1, N]
ans = ans + min(k, (i - j)) * arr[i]
k = k - (i - j)
arr[i] -= 1
# All elements of array are equal
# Send tickets from each counter 1
# time until K > 0.
while (k > 0 and arr[i] != 0):
ans = ans + min(n, k) * arr[i]
k -= n
arr[i] -= 1
ans = ans % mod
# Converting answer from long long
# to int
x = ans
return x
# Driver Code
if __name__ == '__main__':
# Given Input
n = 5
k = 3
arr = [ 4, 3, 6, 2, 4 ]
# Function Call
ans = maxAmount(n, k, arr)
print(ans)
# This code is contributed by avijitmondal1998
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find maximum profit
// after selling K tickets
static int maxAmount(int n, int k, int []arr)
{
// Frequency array to store freq
// of every element of the array
int i;
int []A = new int[1000001];
Array.Clear(A,0,1000001);
for (i = 0; i < n; i++) {
A[arr[i]]++;
}
int j = 0;
// Modify the arr[] so that the
// array is sorted in O(N)
for (i = 0; i < 1000001; i++) {
while (A[i] != 0) {
arr[j++] = i;
A[i]--;
}
}
// Variable to store answer
int ans = 0;
int mod = 1000000007;
i = n - 1;
j = n - 2;
// Traverse the array while K>0
// and j>=0
while (k > 0 && j >= 0) {
// If arr[i] > arr[j] then
// ticket can be brought from
// counter [j+1, N]
if (arr[i] > arr[j]) {
ans = ans + Math.Min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
else {
// If arr[j] == arr[i] decrement j until
// arr[j] != arr[i]
while (j >= 0 && arr[j] == arr[i])
j--;
if (j < 0)
break;
// Sell tickets from counter [j+1, N]
ans = ans + Math.Min(k, (i - j)) * arr[i];
k = k - (i - j);
arr[i]--;
}
}
// All elements of array are equal
// Send tickets from each counter 1
// time until K > 0.
while (k > 0 && arr[i] != 0) {
ans = ans + Math.Min(n, k) * arr[i];
k -= n;
arr[i]--;
}
ans = ans % mod;
// Converting answer from long long
// to int
int x = ans;
return x;
}
// Driver Code
public static void Main()
{
// Given Input
int n = 5;
int k = 3;
int []arr = { 4, 3, 6, 2, 4 };
// Function Call
int ans = maxAmount(n, k, arr);
Console.Write(ans);
}
}
// This code is contributed by ipg2016107.
Javascript
输出
15
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。