📌  相关文章
📜  没有连续元素的子集的最大和

📅  最后修改于: 2022-05-13 01:56:04.450000             🧑  作者: Mango

没有连续元素的子集的最大和

给定一个大小为N的数组arr[] ,任务是找到数组子集的最大可能和,使得没有两个连续元素是子集的一部分。

例子

朴素方法:朴素方法是生成所有可能的子集,并从中检查哪些子集遵循给定条件。计算这些子集的总和,其中的最大值就是所需的答案。

时间复杂度: O(2 N )
辅助空间: O(2 N )

有效方法:一种有效的方法是借助以下思想使用动态规划:

请按照以下步骤解决问题:

  • 使用散列来存储每个元素的频率。
  • 找到数组的最大值。 (说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[] 数组的空间可以优化如下:

下面是上述方法的实现:

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)。