给定一个由 N 个数字组成的数组,我们需要最大化所选数字的总和。在每一步,您需要选择一个数字 A i ,删除它的一次出现,并删除数组中所有出现的A i -1和A i +1 (如果存在)。重复这些步骤直到数组变空。问题是最大化所选数字的总和。
注意:如果 A i +1 和 A i -1 元素存在于数组中而不是 A i+1和 A i-1 ,我们必须删除所有出现的 A i +1 和 A i -1 元素。
例子:
Input : a[] = {1, 2, 3}
Output : 4
Explanation: At first step we select 1, so 1 and
2 are deleted from the sequence leaving us with 3.
Then we select 3 from the sequence and delete it.
So the sum of selected numbers is 1+3 = 4.
Input : a[] = {1, 2, 2, 2, 3, 4}
Output : 10
Explanation : Select one of the 2's from the array, so
2, 2-1, 2+1 will be deleted and we are left with {2, 2, 4},
since 1 and 3 are deleted. Select 2 in next two steps,
and then select 4 in the last step.
We get a sum of 2+2+2+4=10 which is the maximum possible.
我们的目标是最大化所选数字的总和。这个想法是预先计算数组 a[] 中所有数字 x 的出现次数。
方法:
- 计算数组中的 MAX 值。
- 创建一个大小为 MAX 的数组并将每个元素的出现次数存储在其中。
- 由于我们想要最大化我们的答案,我们将从 MAX 值开始迭代到 0。
- 如果第i个元素的发生是大于0,然后将其添加到我们的答案减1的第i-1元素的出现,以及1,因为我们把它添加到我们的答案也减少了第i的发生.
- 我们没有降低i + 1种元素的发生,因为我们已经从年底开始使i + 1个已处理。
- 可能会多次出现第 i个元素,这就是为什么不减少 i 以保持在同一个元素上。
下面是上述想法的实现:
C++
// CPP program to Maximize the sum of selected
// numbers by deleting three consecutive numbers.
#include
using namespace std;
// function to maximize the sum of selected numbers
int maximizeSum(int arr[], int n) {
// Largest element in the array
int mx = -1;
for(int i = 0; i < n; i++)
{
mx = max(mx, arr[i]);
}
// An array to count the occurence of each element
int freq[mx + 1];
memset(freq, 0, sizeof(freq));
for(int i = 0; i < n; i++)
{
freq[arr[i]]++;
}
// ans to store the result
int ans = 0, i=mx;
// Using the above mentioned approach
while(i>0){
// if occurence is greater than 0
if(freq[i] > 0){
// add it to ans
ans += i;
// decrease i-1th element by 1
freq[i-1]--;
// decrease ith element by 1
freq[i]--;
}else{
// decrease i
i--;
}
}
return ans;
}
// Driver code
int main()
{
int a[] = {1, 2, 3};
int n = sizeof(a) / sizeof(a[0]);
cout << maximizeSum(a, n);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
import java.math.*;
class GFG
{
// Function to maximise the sum of selected numbers
//by deleting occurences of Ai-1 and Ai+1
public static int getMaximumSum (int arr[]) {
// Number of elements in the array
int n = arr.length;
// Largest element in the array
int max = -1;
for(int i = 0; i < n; i++)
{
max = Math.max(max, arr[i]);
}
// An array to count the occurence of each element
int []freq = new int[max + 1];
for(int i = 0; i < n; i++)
{
freq[arr[i]]++;
}
// ans to store the result
int ans = 0, i=max;
// Using the above mentioned approach
while(i>0){
// if occurence is greater than 0
if(freq[i] > 0){
// add it to ans
ans += i;
// decrease i-1th element by 1
freq[i-1]--;
// decrease ith element by 1
freq[i]--;
}else{
// decrease i
i--;
}
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int []a = {1, 2, 3};
System.out.println(getMaximumSum(a));
}
}
Python3
# Python3 program to Maximize the sum of selected
# numbers by deleting three consecutive numbers.
# function to maximize the sum of
# selected numbers
def maximizeSum(a, n) :
# maximum in the sequence
maximum = max(a)
# stores the occurrences of the numbers
ans = dict.fromkeys(range(0, n + 1), 0)
# marks the occurrence of every
# number in the sequence
for i in range(n) :
ans[a[i]] += 1
# ans to store the result
result = 0
i = maximum
# Using the above mentioned approach
while i > 0:
# if occurence is greater than 0
if ans[i] > 0:
# add it to ans
result += i;
# decrease i-1th element by 1
ans[i-1] -= 1;
# decrease ith element by 1
ans[i] -= 1;
else:
# decrease i
i -= 1;
return result;
# Driver code
if __name__ == "__main__" :
a = [1, 2, 3]
n = len(a)
print(maximizeSum(a, n))
# This code is contributed by Ryuga
C#
// C# implementation of the approach
using System;
using System.Linq;
class GFG
{
// Function to maximise the sum of selected numbers
//by deleting occurences of Ai-1 and Ai+1
static int getMaximumSum(int []arr)
{
// Number of elements in the array
int n = arr.Length;
// Largest element in the array
int max = arr.Max();
// An array to count the occurence of each element
int []freq = new int[max + 1];
for(int j = 0; j < n; j++)
{
freq[arr[j]]++;
}
// ans to store the result
int ans = 0, i=max;
// Using the above mentioned approach
while(i>0){
// if occurence is greater than 0
if(freq[i] > 0){
// add it to ans
ans += i;
// decrease i-1th element by 1
freq[i-1]--;
// decrease ith element by 1
freq[i]--;
}else{
// decrease i
i--;
}
}
return ans;
}
// Driver code
public static void Main(string[] args)
{
int []a = {1, 2, 3};
Console.Write(getMaximumSum(a));
}
}
// This code is contributed by rock_cool
Javascript
输出:
4
时间复杂度:时间复杂度将是 (A max + arr 中出现次数最多的元素),因为如果频率大于 1,那么我们将多次处理该元素。
– 其中 A max是数组 A[] 中存在的最大元素。
空间复杂度: O(A max ),其中 A max是数组 A[] 中存在的最大元素。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。