给定一个大小为N的正整数数组arr[] ,任务是找到一个子序列的最大和,约束条件是序列中没有 2 个数字应该与该值相邻,即如果arr[i]被纳入答案,那么arr[i]-1和arr[i]+1都不能被选择。
例子:
Input: arr[] = {2, 2, 2}
Output: 6
Explanation:
The max sum subsequence will be [2, 2, 2] as it does not contain any occurrence of 1 or 3. Hence sum = 2 + 2 + 2 = 6
Input: arr[] = {2, 2, 3}
Output: 4
Explanation:
Subsequence 1: [2, 2] as it does not contain any occurrence of 1 or 3. Hence sum = 2 + 2 = 4
Subsequence 2: [3] as it does not contain any occurrence of 2 or 4. Hence sum = 3
Therefore, the max sum = 4
解决方法:思路是使用Dynamic Programming,类似这篇文章。
- 创建一个映射来存储元素 i 在序列中出现的次数。
- 要找到答案,首先将问题分解为更小的问题会很容易。在这种情况下,将序列分解为更小的序列并为其找到最佳解决方案。
- 对于仅包含 0 的数字序列,答案将为 0。类似地,如果序列仅包含数字 0 和 1,则解决方案是 count[1]*1。
- 现在为这个问题构建一个递归解决方案。对于仅包含数字 0 到 n 的数字序列,可以选择是否选择第 N 个元素。
dp[i] = max(dp[i – 1], dp[i – 2] + i*freq[i] )
dp[i-1] represents not picking the ith number, then the number before it can be considered.
dp[i – 2] + i*freq[i] represents picking the ith number, then the number before it is eliminated. Hence, the number before that is considered.
C++
// C++ program to find maximum sum
// subsequence with values
// differing by at least 2
#include
using namespace std;
// function to find maximum sum
// subsequence such that two
// adjacent values elements are
// not selected
int get_max_sum(int arr[], int n)
{
// map to store the frequency
// of array elements
unordered_map freq;
for (int i = 0; i < n; i++) {
freq[arr[i]]++;
}
// make a dp array to store
// answer upto i th value
int dp[100001];
memset(dp, 0, sizeof(dp));
// base cases
dp[0] = 0;
dp[1] = freq[0];
// iterate for all possible
// values of arr[i]
for (int i = 2; i <= 100000; i++) {
dp[i] = max(dp[i - 1],
dp[i - 2] + i * freq[i]);
}
// return the last value
return dp[100000];
}
// Driver function
int main()
{
int N = 3;
int arr[] = { 2, 2, 3 };
cout << get_max_sum(arr, N);
return 0;
}
Java
// Java program to find maximum sum
// subsequence with values
// differing by at least 2
import java.util.*;
import java.lang.*;
class GFG{
// Function to find maximum sum
// subsequence such that two
// adjacent values elements are
// not selected
public static int get_max_sum(int arr[], int n)
{
// map to store the frequency
// of array elements
HashMap freq = new HashMap();
for(int i = 0; i < n; i++)
{
if (freq.containsKey(arr[i]))
{
int x = freq.get(arr[i]);
freq.replace(arr[i], x + 1);
}
else
freq.put(arr[i], 1);
}
// Make a dp array to store
// answer upto i th value
int[] dp = new int[100001];
for(int i = 0; i < 100001; i++)
dp[i] = 0;
// Base cases
dp[0] = 0;
if (freq.containsKey(0))
dp[1] = freq.get(0);
else
dp[1] = 0;
// Iterate for all possible
// values of arr[i]
for(int i = 2; i <= 100000; i++)
{
int temp = (freq.containsKey(i)) ?
freq.get(i) : 0;
dp[i] = Math.max(dp[i - 1],
dp[i - 2] + i * temp);
}
// Return the last value
return dp[100000];
}
// Driver code
public static void main(String[] args)
{
int N = 3;
int arr[] = { 2, 2, 3 };
System.out.println(get_max_sum(arr, N));
}
}
// This code is contributed by grand_master
Python3
# Python3 program to find maximum sum
# subsequence with values
# differing by at least 2
from collections import defaultdict
# Function to find maximum sum
# subsequence such that two
# adjacent values elements are
# not selected
def get_max_sum(arr, n):
# Map to store the frequency
# of array elements
freq = defaultdict(lambda : 0)
for i in range(n):
freq[arr[i]] += 1
# Make a dp array to store
# answer upto i th value
dp = [0] * 100001
# Base cases
dp[0] = 0
dp[1] = freq[0]
# Iterate for all possible
# values of arr[i]
for i in range(2, 100000 + 1):
dp[i] = max(dp[i - 1],
dp[i - 2] + i * freq[i])
# Return the last value
return dp[100000]
# Driver code
N = 3
arr = [ 2, 2, 3 ]
print(get_max_sum(arr, N))
# This code is contributed by stutipathak31jan
C#
// C# program to find maximum sum
// subsequence with values
// differing by at least 2
using System;
using System.Collections.Generic;
class GFG{
// Function to find maximum sum
// subsequence such that two
// adjacent values elements are
// not selected
public static int get_max_sum(int []arr, int n)
{
// map to store the frequency
// of array elements
Dictionary freq = new Dictionary();
for(int i = 0; i < n; i++)
{
if (freq.ContainsKey(arr[i]))
{
int x = freq[arr[i]];
freq[arr[i]]= x + 1;
}
else
freq.Add(arr[i], 1);
}
// Make a dp array to store
// answer upto i th value
int[] dp = new int[100001];
for(int i = 0; i < 100001; i++)
dp[i] = 0;
// Base cases
dp[0] = 0;
if (freq.ContainsKey(0))
dp[1] = freq[0];
else
dp[1] = 0;
// Iterate for all possible
// values of arr[i]
for(int i = 2; i <= 100000; i++)
{
int temp = (freq.ContainsKey(i)) ?
freq[i] : 0;
dp[i] = Math.Max(dp[i - 1],
dp[i - 2] + i * temp);
}
// Return the last value
return dp[100000];
}
// Driver code
public static void Main(String[] args)
{
int N = 3;
int []arr = { 2, 2, 3 };
Console.WriteLine(get_max_sum(arr, N));
}
}
// This code is contributed by Amit Katiyar
Javascript
4
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。