给定一个由长度为N的整数和整数K ( 1≤k≤N)组成的数组arr [] ,任务是找到数组中的最大子序列和,以使该子序列中的相邻元素至少相差K在原始数组中的索引中。
例子:
Input: arr[] = {1, 2, -2, 4, 3, 1}, K = 4
Output: 4
Explanation:
Such Subsequences that can be selected: {1, 3}, {1, 1}, {2, 1}
Subsequence with maximum sum = (1 + 3) = 4
Selected elements are a[0] and a[4] (difference between indices = 4)
Input: arr[] = {1, 2, 72, 4, 3}, K = 2
Output: 76
Explanation:
Such Subsequences that can be selected – {{1, 72, 3}, {2, 4}, {2, 3}, {1, 4}, {1, 3}}
Subsequence with maximum sum = (1 + 72 + 3) = 76
Selected elements are a[0], a[2] and a[4] (difference between each indices = 2)
天真的方法:生成数组的所有可能子集,并检查每个子集是否满足条件,以使两个相邻元素的索引至少具有K的差。如果是,则将其总和与迄今为止获得的最大总和进行比较,如果该总和大于迄今为止获得的总和,则对其进行更新。
有效方法:可以使用动态编程解决此问题。对于数组中的每个元素,请考虑以下因素:如果我们采用该元素,则它有助于最终获得的总和。如果是,则将其添加到该元素的DP数组中。
让我们确定“ dp”的状态。令dp [i]是从索引’0’开始并以索引’i’结束的子数组的最大可能和。现在,我们必须找到此状态与低阶状态之间的递归关系。
现在,数组的递归关系将对每个索引i有两个选择。
- 选择当前索引:
在这种情况下,可以选择的元素位于索引ik。
所以,dp[i] = arr[i] + dp[i - k]
- 跳过当前索引。
在这种情况下,可以选择的元素在索引i-1处。
所以,dp[i] = dp[i - 1]
对于每个索引,请选择在该索引处给出最大总和的条件,因此最终的递归关系将是:
dp[i] = max(dp[i – 1], arr[i] + dp[i – k])
下面是上述方法的实现。
C++
// C++ implementation to find the
// maximum sum subsequence such that
// two adjacent element have atleast
// difference of K in their indices
#include
using namespace std;
// Function to find the maximum
// between two elements a and b
int maxi(int a, int b)
{
if (a > b) {
return a;
}
else {
return b;
}
}
// Function to find the maximum sum
// subsequence such that two adjacent
// element have atleast difference
// of K in their indices
int max_sum(int arr[], int n, int k)
{
// DP Array to store the maximum
// sum obtained till now
int dp[n];
// Either select the first element
// or Nothing
dp[0] = maxi(0, arr[0]);
int i = 1;
// Either Select the (i - 1) element
// or let the previous best answer be
// the current best answer
while (i < k) {
dp[i] = maxi(dp[i - 1], arr[i]);
i++;
}
i = k;
// Either select the best sum
// till previous_index or select the
// current element + best_sum till index-k
while (i < n) {
dp[i] = maxi(dp[i - 1], arr[i] + dp[i - k]);
i++;
}
return dp[n - 1];
}
// Driver Code
int main()
{
int arr[] = { 1, 2, -2, 4, 3, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 4;
cout << max_sum(arr, n, k);
return 0;
}
Java
// Java implementation to find the
// maximum sum subsequence such that
// two adjacent element have atleast
// difference of K in their indices
class GFG
{
// Function to find the maximum sum
// subsequence such that two adjacent
// element have atleast difference
// of K in their indices
static int max_sum(int arr[], int n, int k)
{
// DP Array to store the maximum
// sum obtained till now
int dp[] = new int[n];
// Either select the first element
// or Nothing
dp[0] = Math.max(0, arr[0]);
int i = 1;
// Either Select the (i - 1) element
// or let the previous best answer be
// the current best answer
while (i < k)
{
dp[i] = Math.max(dp[i - 1], arr[i]);
i++;
}
i = k;
// Either select the best sum
// till previous_index or select the
// current element + best_sum till index-k
while (i < n)
{
dp[i] = Math.max(dp[i - 1],
arr[i] + dp[i - k]);
i++;
}
return dp[n - 1];
}
// Driver Code
public static void main (String[] args)
{
int arr[] = { 1, 2, -2, 4, 3, 1 };
int n = arr.length;
int k = 4;
System.out.println(max_sum(arr, n, k));
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 implementation to find the
# maximum sum subsequence such that
# two adjacent element have atleast
# difference of K in their indices
# Function to find the maximum sum
# subsequence such that two adjacent
# element have atleast difference
# of K in their indices
def max_sum(arr, n, k) :
# DP Array to store the maximum
# sum obtained till now
dp = [0] * n;
# Either select the first element
# or Nothing
dp[0] = max(0, arr[0]);
i = 1;
# Either Select the (i - 1) element
# or let the previous best answer be
# the current best answer
while (i < k) :
dp[i] = max(dp[i - 1], arr[i]);
i += 1;
i = k;
# Either select the best sum
# till previous_index or select the
# current element + best_sum till index-k
while (i < n) :
dp[i] = max(dp[i - 1], arr[i] + dp[i - k]);
i += 1;
return dp[n - 1];
# Driver Code
if __name__ == "__main__" :
arr = [ 1, 2, -2, 4, 3, 1 ];
n = len(arr)
k = 4;
print(max_sum(arr, n, k));
# This code is contributed by AnkitRai01
C#
// C# implementation to find the
// maximum sum subsequence such that
// two adjacent element have atleast
// difference of K in their indices
using System;
class GFG
{
// Function to find the maximum sum
// subsequence such that two adjacent
// element have atleast difference
// of K in their indices
static int max_sum(int []arr, int n, int k)
{
// DP Array to store the maximum
// sum obtained till now
int []dp = new int[n];
// Either select the first element
// or Nothing
dp[0] = Math.Max(0, arr[0]);
int i = 1;
// Either Select the (i - 1) element
// or let the previous best answer be
// the current best answer
while (i < k)
{
dp[i] = Math.Max(dp[i - 1], arr[i]);
i++;
}
i = k;
// Either select the best sum
// till previous_index or select the
// current element + best_sum till index-k
while (i < n)
{
dp[i] = Math.Max(dp[i - 1],
arr[i] + dp[i - k]);
i++;
}
return dp[n - 1];
}
// Driver Code
public static void Main()
{
int []arr = { 1, 2, -2, 4, 3, 1 };
int n = arr.Length;
int k = 4;
Console.WriteLine(max_sum(arr, n, k));
}
}
// This code is contributed by AnkitRai01
4
时间复杂度: O(N)
辅助空间: O(N)