给定一个由长度为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
Javascript
4
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live