没有连续元素的子集的最大和
给定一个大小为N的数组arr[] ,任务是找到数组子集的最大可能和,使得没有两个连续元素是子集的一部分。
例子:
Input: arr[]= {2, 3, 2, 3, 3, 4}
Output: 9
Explanation: The subset having all the 3s i.e. {3, 3, 3} have sum = 9.
This is the maximum possible sum of any possible subset of the array following the condition.
Input: arr[] = {2, 3, 4}
Output: 6
Explanation: The subset is {2, 4}. It has sum = 6 which is the maximum possible.
朴素方法:朴素方法是生成所有可能的子集,并从中检查哪些子集遵循给定条件。计算这些子集的总和,其中的最大值就是所需的答案。
时间复杂度: O(2 N )
辅助空间: O(2 N )
有效方法:一种有效的方法是借助以下思想使用动态规划:
For any element X in arr[], the value X-1 cannot be considered but all the elements having value X can be. So for X the maximum possible answer till X is maximum between (maximum possible answer till X-2 + freq(X)*X) and (maximum possible answer till X-1)
请按照以下步骤解决问题:
- 使用散列来存储每个元素的频率。
- 找到数组的最大值。 (说X )
- 创建一个dp[]数组,其中dp[i]存储当值最多为i的元素包含在子集中时的最大可能子集总和。
- 从i = 2 迭代到数组的 X :
- 根据观察值dp[i] = max(dp[i-2] + i*freq(i), dp[i-1])根据公式计算 dp[i] 的值。
- dp[] 数组中的最大值就是答案。
下面是上述方法的实现。
C++
// C++ code to implement the approach
#include
using namespace std;
// Function to calculate the maximum value
int MaximiseStockPurchase(vector& nums,
int n)
{
int maxi = 0;
for (int i = 0; i < n; i++)
maxi = max(maxi, nums[i]);
vector freq(maxi + 1, 0);
vector dp(maxi + 1, 0);
for (auto i : nums)
freq[i]++;
dp[1] = freq[1];
// Loop to calculate dp[] array
// till max element of array
for (int i = 2; i <= maxi; i++)
dp[i] = max(dp[i - 2] + i * freq[i],
dp[i - 1]);
return dp[maxi];
}
// Driver code
int main()
{
vector arr{ 2, 2, 3, 4, 3, 3 };
int N = arr.size();
int res = MaximiseStockPurchase(arr, N);
cout << res;
return 0;
}
Java
// Java code to implement the approach
import java.io.*;
class GFG {
// Function to calculate the maximum value
static int MaximiseStockPurchase(int nums[],
int n)
{
int maxi = 0;
for (int i = 0; i < n; i++)
maxi = Math.max(maxi, nums[i]);
int freq[] = new int[maxi + 1];
int dp[] = new int[maxi + 1];
for (int i = 0; i < n; i++)
freq[nums[i]]++;
dp[1] = freq[1];
// Loop to calculate dp[] array
// till max element of array
for (int i = 2; i <= maxi; i++)
dp[i] = Math.max(dp[i - 2] + i * freq[i],
dp[i - 1]);
return dp[maxi];
}
// Driver code
public static void main (String[] args) {
int arr[] = { 2, 2, 3, 4, 3, 3 };
int N = arr.length;
int res = MaximiseStockPurchase(arr, N);
System.out.println(res);
}
}
// This code is contributed by hrithikgarg03188.
Python3
# Python 3 code to implement the approach
# Function to calculate the maximum value
def MaximiseStockPurchase(nums, n):
maxi = 0
for i in range(n):
maxi = max(maxi, nums[i])
freq = [0]*(maxi + 1)
dp = [0] * (maxi + 1)
for i in nums:
freq[i] += 1
dp[1] = freq[1]
# Loop to calculate dp[] array
# till max element of array
for i in range(2, maxi + 1):
dp[i] = max(dp[i - 2] + i * freq[i],
dp[i - 1])
return dp[maxi]
# Driver code
if __name__ == "__main__":
arr = [2, 2, 3, 4, 3, 3]
N = len(arr)
res = MaximiseStockPurchase(arr, N)
print(res)
# This code is contributed by ukasp.
C#
// C# code to implement the approach
using System;
class GFG {
// Function to calculate the maximum value
static int MaximiseStockPurchase(int[] nums, int n)
{
int maxi = 0;
for (int i = 0; i < n; i++)
maxi = Math.Max(maxi, nums[i]);
int[] freq = new int[maxi + 1];
int[] dp = new int[maxi + 1];
for (int i = 0; i < n; i++)
freq[nums[i]]++;
dp[1] = freq[1];
// Loop to calculate dp[] array
// till max element of array
for (int i = 2; i <= maxi; i++)
dp[i] = Math.Max(dp[i - 2] + i * freq[i],
dp[i - 1]);
return dp[maxi];
}
// Driver code
public static void Main()
{
int[] arr = { 2, 2, 3, 4, 3, 3 };
int N = arr.Length;
int res = MaximiseStockPurchase(arr, N);
Console.WriteLine(res);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
C++
// C++ code to implement the approach
#include
using namespace std;
// Function to calculate the maximum sum
int MaximiseStockPurchase(vector& nums,
int n)
{
int maxNum = INT_MIN;
for (auto i : nums)
maxNum = max(maxNum, i);
vector freq(maxNum + 1, 0);
for (auto i : nums)
freq[i]++;
int curPoints = freq[1], prevPoints = 0;
// Loop to calculate the sum
for (int i = 2; i <= maxNum; i++) {
int tmp = curPoints;
curPoints = max(prevPoints + i * freq[i],
curPoints);
prevPoints = tmp;
}
return curPoints;
}
// Driver code
int main()
{
vector arr{ 2, 2, 3, 4, 3, 3 };
int N = arr.size();
int res = MaximiseStockPurchase(arr, N);
cout << res;
return 0;
}
Java
// Java implementation of above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to calculate the maximum sum
static int MaximiseStockPurchase(int[] nums, int n)
{
int maxNum = Integer.MIN_VALUE;
for(int i : nums) maxNum = Math.max(maxNum, i);
int[] freq = new int[maxNum + 1];
for (int x = 0; x < maxNum; x++) {
freq[x] = 0;
}
for(int i : nums) freq[i]++;
int curPoints = freq[1], prevPoints = 0;
// Loop to calculate the sum
for (int i = 2; i <= maxNum; i++) {
int tmp = curPoints;
curPoints = Math.max(prevPoints + i * freq[i],
curPoints);
prevPoints = tmp;
}
return curPoints;
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 2, 2, 3, 4, 3, 3 };
int N = arr.length;
int res = MaximiseStockPurchase(arr, N);
System.out.print(res);
}
}
// This code is contributed by code_hunt.
Python3
# Python code to implement the approach
# Function to calculate the maximum sum
import sys
def MaximiseStockPurchase(nums,n):
maxNum = -sys.maxsize -1
for i in nums:
maxNum = max(maxNum, i)
freq = [0 for i in range(maxNum+1)]
for i in nums:
freq[i] += 1
curPoints,prevPoints = freq[1],0
# Loop to calculate the sum
for i in range(2,maxNum+1):
tmp = curPoints
curPoints = max(prevPoints + i * freq[i],curPoints)
prevPoints = tmp
return curPoints
# Driver code
arr = [ 2, 2, 3, 4, 3, 3 ]
N = len(arr)
res = MaximiseStockPurchase(arr, N)
print(res)
# This code is contributed by shinjanpatra
C#
// C# code to implement the approach
using System;
class GFG {
// Function to calculate the maximum sum
static int MaximiseStockPurchase(int[] nums, int n)
{
int maxNum = Int32.MinValue;
foreach(int i in nums) maxNum = Math.Max(maxNum, i);
int[] freq = new int[maxNum + 1];
for (int x = 0; x < maxNum; x++) {
freq[x] = 0;
}
foreach(int i in nums) freq[i]++;
int curPoints = freq[1], prevPoints = 0;
// Loop to calculate the sum
for (int i = 2; i <= maxNum; i++) {
int tmp = curPoints;
curPoints = Math.Max(prevPoints + i * freq[i],
curPoints);
prevPoints = tmp;
}
return curPoints;
}
// Driver code
public static void Main()
{
int[] arr = { 2, 2, 3, 4, 3, 3 };
int N = arr.Length;
int res = MaximiseStockPurchase(arr, N);
Console.Write(res);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
9
时间复杂度: O(M),其中 M 是数组的最大元素。
辅助空间:O(M)
替代方法:在上述方法中,dp[] 数组的空间可以优化如下:
As seen from the observation we only need the value of dp[i-1] and dp[i-2] to calculate the value of dp[i]. So instead of using dp[] array use two variables to store the value of the previous two steps.
下面是上述方法的实现:
C++
// C++ code to implement the approach
#include
using namespace std;
// Function to calculate the maximum sum
int MaximiseStockPurchase(vector& nums,
int n)
{
int maxNum = INT_MIN;
for (auto i : nums)
maxNum = max(maxNum, i);
vector freq(maxNum + 1, 0);
for (auto i : nums)
freq[i]++;
int curPoints = freq[1], prevPoints = 0;
// Loop to calculate the sum
for (int i = 2; i <= maxNum; i++) {
int tmp = curPoints;
curPoints = max(prevPoints + i * freq[i],
curPoints);
prevPoints = tmp;
}
return curPoints;
}
// Driver code
int main()
{
vector arr{ 2, 2, 3, 4, 3, 3 };
int N = arr.size();
int res = MaximiseStockPurchase(arr, N);
cout << res;
return 0;
}
Java
// Java implementation of above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to calculate the maximum sum
static int MaximiseStockPurchase(int[] nums, int n)
{
int maxNum = Integer.MIN_VALUE;
for(int i : nums) maxNum = Math.max(maxNum, i);
int[] freq = new int[maxNum + 1];
for (int x = 0; x < maxNum; x++) {
freq[x] = 0;
}
for(int i : nums) freq[i]++;
int curPoints = freq[1], prevPoints = 0;
// Loop to calculate the sum
for (int i = 2; i <= maxNum; i++) {
int tmp = curPoints;
curPoints = Math.max(prevPoints + i * freq[i],
curPoints);
prevPoints = tmp;
}
return curPoints;
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 2, 2, 3, 4, 3, 3 };
int N = arr.length;
int res = MaximiseStockPurchase(arr, N);
System.out.print(res);
}
}
// This code is contributed by code_hunt.
Python3
# Python code to implement the approach
# Function to calculate the maximum sum
import sys
def MaximiseStockPurchase(nums,n):
maxNum = -sys.maxsize -1
for i in nums:
maxNum = max(maxNum, i)
freq = [0 for i in range(maxNum+1)]
for i in nums:
freq[i] += 1
curPoints,prevPoints = freq[1],0
# Loop to calculate the sum
for i in range(2,maxNum+1):
tmp = curPoints
curPoints = max(prevPoints + i * freq[i],curPoints)
prevPoints = tmp
return curPoints
# Driver code
arr = [ 2, 2, 3, 4, 3, 3 ]
N = len(arr)
res = MaximiseStockPurchase(arr, N)
print(res)
# This code is contributed by shinjanpatra
C#
// C# code to implement the approach
using System;
class GFG {
// Function to calculate the maximum sum
static int MaximiseStockPurchase(int[] nums, int n)
{
int maxNum = Int32.MinValue;
foreach(int i in nums) maxNum = Math.Max(maxNum, i);
int[] freq = new int[maxNum + 1];
for (int x = 0; x < maxNum; x++) {
freq[x] = 0;
}
foreach(int i in nums) freq[i]++;
int curPoints = freq[1], prevPoints = 0;
// Loop to calculate the sum
for (int i = 2; i <= maxNum; i++) {
int tmp = curPoints;
curPoints = Math.Max(prevPoints + i * freq[i],
curPoints);
prevPoints = tmp;
}
return curPoints;
}
// Driver code
public static void Main()
{
int[] arr = { 2, 2, 3, 4, 3, 3 };
int N = arr.Length;
int res = MaximiseStockPurchase(arr, N);
Console.Write(res);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
9
时间复杂度:O(N + M) 其中 M 是数组的最大元素
辅助空间: O(M)。