给定一个由长度为N的整数和一个整数K (1 <= K <= N) 组成的数组arr[] ,任务是找到数组中的最大子序列和,使得该子序列中的相邻元素具有它们在原始数组中的索引最多相差K。换句话说,如果i和j是原始数组中子序列的两个连续元素的索引,则|ij| <= K。
例子:
Input: arr[] = {1, 2, -2, 4, 3, 1}, K = 2
Output: 11
Explanation : The sub–sequence with maximum sum is {1, 2, 4, 3, 1} (difference between indices <=2)
Input: arr[] = {4, -2, -2, -1, 3, -1}, K = 2
Output: 5
Explanation : The sub-sequence with maximum sum is {4, -2, 3} (difference between indices <=2)
朴素的方法:生成数组的所有可能子集,并检查每个子集是否满足两个相邻元素在其索引中最多具有 K 差的条件。如果是,则将其总和与迄今为止获得的最大总和进行比较,如果它大于迄今为止获得的总和,则更新总和。
有效的方法:这个问题可以使用动态规划来解决。
创建一个表dp[] ,其中dp[i]存储子序列的最大可能总和,直到第i个索引。
- 如果当前元素是子序列的第一个元素,则:
dp[i] =arr[i]
- 否则,我们必须检查以前的结果,并检查此索引后面的K窗口中 dp 的最大结果是什么:
dp[i] = max(arr[i] + dp[x]) where x is from [i-k, i-1]
- 对于每个索引,选择在该索引处给出最大总和的条件,所以最终的递推关系将是:
dp[i] = max(arr[i], arr[i] + dp[x]) where i-k <= x <= i-1
因此,为了检查K的窗口中该索引后面的最大值是多少,我们可以从 dp[i-1] 迭代到 dp[ik] 并找到最大值,在这种情况下,时间复杂度将为O( N*K)或者可以通过采用有序映射并保持每个索引的计算 dp[i] 值来减少它。这将复杂性降低到O(N*log(K)) 。
下面是上述方法的实现。
C++
// C++ implementation to
// C++ program to
// find the maximum sum
// subsequence such that
// two adjacent element
// have atmost difference
// of K in their indices
#include
#include
#include
Java
// Java program to
// find the maximum sum
// subsequence such that
// two adjacent element
// have atmost difference
// of K in their indices
import java.util.*;
class GFG
{
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];
// Ordered map to store DP
// values in a window ok K
HashMap mp = new HashMap<>();
// Initializing dp[0]=arr[0]
dp[0] = arr[0];
// Inserting value of DP[0]
// in map
if(mp.containsKey(dp[0]))
{
mp.put(dp[0], mp.get(dp[0]) + 1);
}
else{
mp.put(dp[0], 1);
}
// Intializing final answer
// with dp[0]
int ans = dp[0];
for (int i = 1; i < N; i++)
{
// when i keySet = mp.keySet();
ArrayList Keys = new ArrayList(keySet);
dp[i] = Math.max(Keys.get(Keys.size()-1) + arr[i], arr[i]);
// Inserting dp value in map
if(mp.containsKey(dp[i]))
{
mp.put(dp[i], mp.get(dp[i]) + 1);
}
else{
mp.put(dp[i], 1);
}
}
else {
Set keySet = mp.keySet();
ArrayList Keys = new ArrayList(keySet);
dp[i] = Math.max(Keys.get(Keys.size()-1) + arr[i], arr[i]);
if(mp.containsKey(dp[i]))
{
mp.put(dp[i], mp.get(dp[i]) + 1);
}
else{
mp.put(dp[i], 1);
}
// Deleting dp[i-k] from
// map beacuse window size
// has become K+1
if(mp.containsKey(dp[i - K]))
{
mp.put(dp[i - K], mp.get(dp[i - K]) - 1);
}
else{
mp.put(dp[i - K], - 1);
}
// Erase the key from if
// count of dp[i-K] becomes
// zero
if (mp.get(dp[i - K]) == 0)
{
mp.remove(dp[i - K]);
}
}
// Calculating final answer
ans = Math.max(ans, dp[i]);
}
return ans;
}
// Driver code
public static void main(String[] args) {
int[] arr = { 1, 2, -2,
4, 3, 1 };
int N = arr.length;
int K = 2;
System.out.println(max_sum(arr, N, K));
}
}
// This code is contributed by divyesh072019
Python3
# Python3 program to
# find the maximum sum
# subsequence such that
# two adjacent element
# have atmost difference
# of K in their indices
def max_sum(arr, N, K):
# DP Array to store the
# maximum sum obtained
# till now
dp = [0 for i in range(N)]
# Ordered map to store DP
# values in a window ok K
mp = dict()
# Initializing dp[0]=arr[0]
dp[0] = arr[0];
# Inserting value of DP[0]
# in map
mp[dp[0]] = 1
# Intializing final answer
# with dp[0]
ans = dp[0];
for i in range(1, N):
# when i
C#
// C# program to
// find the maximum sum
// subsequence such that
// two adjacent element
// have atmost difference
// of K in their indices
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
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];
// Ordered map to store DP
// values in a window ok K
Dictionary mp = new Dictionary();
// Initializing dp[0]=arr[0]
dp[0] = arr[0];
// Inserting value of DP[0]
// in map
if(mp.ContainsKey(dp[0]))
{
mp[dp[0]]++;
}
else{
mp[dp[0]] = 1;
}
// Intializing final answer
// with dp[0]
int ans = dp[0];
for (int i = 1; i < N; i++)
{
// when i
11
时间复杂度: O(N*log(K))
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live