通过删除 A[i] 的一次出现以及 A[i]+1 和 A[i]-1 的所有出现来减少数组并最大化总和
给定一个具有N个正整数的数组A[] ,任务是执行以下操作,并在减少数组的同时最大化获得的总和:
- 选择一个数组元素(比如A[i] )并删除该元素的一次出现并将 A[i] 添加到总和中。
- 删除所有出现的A[i]-1和A[i]+1 。
- 执行这些操作,直到数组为空。
例子:
Input: A[] = {3, 4, 2}
Output: 6
Explanation: First, delete number 4 to add 4 to sum and consequently 3 is also deleted.
After that the array A = [2].
Then we delete number 2 and add 2.
Array becomes empty i.e. array A = [].
And hence total sum = (4 + 2) = 6
Input: A[] = {2, 2, 3, 3, 3, 4}
Output: 9
Explanation: First, delete number 3 to add 3. And all 2’s and 4’s numbers are also deleted.
After that we the array is A = [3, 3].
Then delete number 3 again to add 3 points. Sum = 3 + 3 = 6.
The array is now A = [3].
In last operation delete number 3 once again to add 3. Sum = 6+3 = 9.
Now array becomes empty.
Hence maximum sum obtained is 9.
天真的方法:天真的方法是尝试以所有可能的方式减少数组,即对于可以选择的任何值(例如A[i] )并且可以删除该元素的一次出现或任何其他元素的差异为1可以选择带有 A[i] 的(如果它存在于数组中),并且可以删除其中的一个。
时间复杂度: O(2 N )
辅助空间: O(N)
有效的方法:这个问题可以使用基于以下思想的动态规划来解决:
If an element x is deleted once then all occurrences of x-1 and x+1 will be removed from array.
- So, if all array elements having value from 0 till x is considered then maximum sum till x depends on maximum sum till x-2 and maximum sum till x-1, i.e. if x is included then x-1 cannot be included and vice versa. [No need to consider the x+1 or x+2 because here iteration is from lower value to upper value side]
- Suppose these max values for each x are stored in an array (say dp[]) then dp[x] = max(dp[x-1], dp[x-2]+x*occurrences of x).
请按照下图更好地理解。
插图:
Consider an array A[] = {2, 2, 3, 3, 3, 4}
So the frequency of elements will be:
freq = {{2 -> 2}, {3 -> 3}, {4 -> 1}}
Maximum of array is 4.
So the dp[] array will be of size 5.
The dp[] array will be {0, 0, 0, 0, 0}
For x = 2:
=> dp[2] = max(dp[1], dp[0] + freq[2]*2)
= max(0, 2*2) = max(0, 0 + 4) = 4
=> dp[] = {0, 0, 4, 0, 0}
For x = 3:
=> dp[3] = max(dp[2], dp[1] + freq[3]*3)
= max(4, 0 + 3*3) = max(0, 9) = 9
=> dp[] = {0, 0, 4, 9, 0}
For x = 4:
=> dp[4] = max(dp[3], dp[2] + freq[4]*4)
= max(9, 4 + 4*1) = max(9, 8) = 9
=> dp[] = {0, 0, 4, 9, 9}
So the answer is dp[4] = 9 which is the maximum possible sum
按照下面提到的步骤来实现上述观察:
- 创建一个 unordered_map mp来存储每个数组元素的频率。
- 计算数组的最大值(比如max_val )。
- 创建一个数组dp[]来存储观测值中的最大值,并将dp[1]初始化为 1 的计数。
- 从i = 2 迭代到 max_val :
- 如上所述计算dp[i] 。
- 在所有迭代后返回dp[max_val]作为答案,因为它拥有最大可能的总和。
下面是上述方法的实现:
C++
// C++ program to implement the approach
#include
using namespace std;
// Function to return Maximum number
// of points that can be earned
int MaximumPoints(int A[], int array_size)
{
// Maximum element in array A
int element_max = *max_element(A, A
+ array_size);
unordered_map mp;
// Dp array for storing points
int dp[element_max + 1] = { 0 };
// Storing frequency of integers
for (int i = 0; i < array_size; i++) {
mp[A[i]]++;
}
dp[0] = 0;
dp[1] = mp[1];
// Calculation for getting maximum sum
// in dp[] array at every steps
for (int i = 2; i <= element_max; i++) {
dp[i] = max(dp[i - 1],
dp[i - 2] + mp[i] * i);
}
// Returning the maximum sum
return dp[element_max];
}
int main()
{
int A[] = { 2, 2, 3, 3, 3, 4 };
// Size of Array
int array_size = sizeof(A) / sizeof(A[0]);
// Function call
cout << MaximumPoints(A, array_size);
return 0;
}
Java
// Java program to implement the approach
import java.util.*;
import java.util.Arrays;
public class GFG {
// Function to return Maximum number
// of points that can be earned
static int MaximumPoints(int A[], int array_size)
{
// Maximum element in array A
int element_max =Arrays.stream(A).max().getAsInt();
HashMap mp = new HashMap<>();
// Dp array for storing points
int dp[] = new int[element_max + 1];
// Storing frequency of integers
for (int i = 0; i < array_size; i++) {
if(mp.containsKey(A[i])){
mp.put(A[i], mp.get(A[i]) + 1);
}
else{
mp.put(A[i], 1);
}
}
dp[0] = 0;
if(mp.containsKey(1))
dp[1] = mp.get(1);
// Calculation for getting maximum sum
// in dp[] array at every steps
for (int i = 2; i <= element_max; i++) {
dp[i] = Math.max(dp[i - 1],
dp[i - 2] + mp.get(i) * i);
}
// Returning the maximum sum
return dp[element_max];
}
// Driver Code
public static void main (String[] args) {
int A[] = { 2, 2, 3, 3, 3, 4 };
// Size of Array
int array_size = A.length;
// Function call
System.out.print(MaximumPoints(A, array_size));
}
}
// This code is contributed by hrithikgarg03188.
Python3
# Python program to implement the approach
# Function to return Maximum number
# of points that can be earned
def MaximumPoints(A, array_size):
# Maximum element in array A
element_max = max(A)
mp = {}
# Dp array for storing points
dp = [0 for i in range(element_max + 1)]
# Storing frequency of integers
for i in range(array_size):
if (A[i] in mp):
mp[A[i]] = mp[A[i]] + 1
else:
mp[A[i]] = 1
if(1 in mp):
dp[1] = mp[1]
# Calculation for getting maximum sum
# in dp[] array at every steps
for i in range(2,element_max+1):
dp[i] = (max(dp[i - 1], dp[i - 2] + mp[i] * i))
# Returning the maximum sum
return dp[element_max]
A = [ 2, 2, 3, 3, 3, 4 ]
# Size of Array
array_size = len(A)
# Function call
print(MaximumPoints(A, array_size))
# This code is contributed by shinjanpatra
C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG
{
// Function to return Maximum number
// of points that can be earned
static int MaximumPoints(int[] A, int array_size)
{
// Maximum element in array A
int element_max = A.Max();
Dictionary mp
= new Dictionary();
// Dp array for storing points
int[] dp = new int[element_max + 1];
// Storing frequency of integers
for (int i = 0; i < array_size; i++) {
if (mp.ContainsKey(A[i])) {
mp[A[i]] += 1;
}
else {
mp[A[i]] = 1;
}
}
dp[0] = 0;
if (mp.ContainsKey(1))
dp[1] = mp[1];
// Calculation for getting maximum sum
// in dp[] array at every steps
for (int i = 2; i <= element_max; i++) {
dp[i] = Math.Max(dp[i - 1],
dp[i - 2] + mp[i] * i);
}
// Returning the maximum sum
return dp[element_max];
}
// Driver Code
public static void Main(string[] args)
{
int[] A = { 2, 2, 3, 3, 3, 4 };
// Size of Array
int array_size = A.Length;
// Function call
Console.Write(MaximumPoints(A, array_size));
}
}
// This code is contributed by phasing17.
Javascript
// JavaScript program to implement the approach
// Function to return Maximum number
// of points that can be earned
function MaximumPoints(A, array_size)
{
// Maximum element in array A
var element_max = Math.max(... A);
mp = {};
// Dp array for storing points
var dp = [];
// Storing frequency of integers
for (var i = 0; i < array_size; i++) {
if (mp.hasOwnProperty(A[i]))
mp[A[i]] = mp[A[i]] + 1;
else {
mp[A[i]] = 1;
}
}
dp.push(0);
if (dp.hasOwnProperty(1))
dp.push(mp[1]);
else
dp.push(0);
// Calculation for getting maximum sum
// in dp[] array at every steps
for (var i = 2; i <= element_max; i++) {
dp.push(Math.max(dp[i - 1], dp[i - 2] + mp[i] * i));
}
// Returning the maximum sum
return dp[element_max];
}
var A = [ 2, 2, 3, 3, 3, 4 ];
// Size of Array
var array_size = A.length;
// Function call
console.log(MaximumPoints(A, array_size));
// this code was contributed by phasing17
9
时间复杂度: O(N)
辅助空间: O(M),其中 M 是数组的最大元素