给定大小为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: 6
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 max sum = 4
解决方案方法:想法是使用动态编程,类似于本文。
- 创建一个映射以存储元素i在序列中出现的次数。
- 为了找到答案,首先将问题分解为较小的问题很容易。在这种情况下,请将序列分解为较小的序列,并为其找到最佳解决方案。
- 对于仅包含0的数字序列,答案将为0。类似地,如果序列仅包含数字0和1,则解决方案将为count [1] * 1。
- 现在为这个问题建立一个递归的解决方案。对于仅包含数字0到n的数字序列,选择是选择第N个元素还是不选择第N个元素。
dp[i] = max(dp[i – 1], dp[i – 2] + i*freq[i] )
dp[i-1] represent not picking the ith number, then the number before it can be considered.
dp[i – 2] + i*freq[i] represent picking the ith number, then the number before it is eliminated, hence the number before that is considered
C++
// C++ progrm 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 arrray 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 progrm 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 arrray 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 arrray 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# progrm 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 arrray 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
4
时间复杂度: O(N)
辅助空间: O(N)