给定由N个整数和整数K组成的数组arr [] ,任务是在满足以下条件的子序列中打印可能的最大和:
- 子序列中包含元素arr [N – 1]和arr [0]。
- 子序列中的相邻元素之间的距离最多为K个索引。
例子:
Input: arr[] = {10, -5, -2, 4, 0, 3}, K = 3
Output: 17
Explanation:
One of possible way is as follows:
Include arr[0] into the subsequence. Sum = 10.
Include arr[3] in the subsequence. Therefore, sum = 10 + 4 = 14.
Include arr[5] in the subsequence. Therefore, total sum = 14 + 3 = 17.
Therefore, the maximum sum possible is 17.
Input: arr[] = {1, -5, -20, 4, -1, 3, -6, -3}, K = 2
Output: 0
天真的方法:最简单的方法是从arr []中找到所有可能的子序列,相邻元素的索引之间的差异最多为K ,从索引0开始到索引(N – 1)结束。计算所有这些子序列的总和。最后,打印获得的所有总和的最大值。
时间复杂度: O(N * 2 N )
辅助空间: O(N)
高效的方法:可以通过使用贪婪算法和双端队列来优化上述方法。请按照以下步骤解决问题:
- 初始化一个数组,例如dp [] ,以存储在当前索引之前获得的最大值。
- 初始化成对的双端队列,例如Q ,以存储对{dp [i],i} 。
- 将arr [0]的值分配给dp [0]并将对{dp [0],0}放入双端队列。
- 使用变量i遍历给定的数组arr []并执行以下步骤:
- 将dp [i]增加arr [i]与双端队列的最大值之和,即dp [i] = arr [i] + Q [0] [0] 。
- 如果Q [-1] [0]小于dp [i],则从末尾遍历双端队列Q并弹出最后一个元素。
- 将双{dp [i],i}附加在双端队列中。
- 检查双端队列q的第一个元素的索引是否等于(i – K) ,然后从双端队列Q弹出第一个元素。
- 完成上述步骤后,打印存储在dp []的最后一个索引处的值,即dp [N – 1]作为结果。
下面是上述方法的实现:
C++
// CPP program for the above approach
#include
using namespace std;
// Function to find maximum sum
// of a subsequence satisfying
// the given conditions
int maxResult(int arr[], int k, int n){
// Stores the maximum sum
int dp[n] = {0};
// Starting index of
// the subsequence
dp[0] = arr[0];
// Stores the pair of maximum value
// and the index of that value
deque> q;
q.push_back({arr[0], 0});
// Traverse the array
for (int i = 1; i < n; i++)
{
// Increment the first value
// of deque by arr[i] and
// store it in dp[i]
dp[i] = arr[i] + q.front().first;
// Delete all the values which
// are less than dp[i] in deque
while (q.size() > 0 and q.back().first < dp[i])
q.pop_back();
// Append the current pair of
// value and index in deque
q.push_back({dp[i], i});
// If first value of the
// queue is at a distance > K
if (i - k == q.front().second)
q.pop_front();
}
// Return the value at the last index
return dp[n - 1];
}
// Driver Code
int main()
{
int arr[] = {10, -5, -2, 4, 0, 3};
int K = 3;
int n = sizeof(arr)/sizeof(arr[0]);
cout<
Python3
# Python program for the above approach
from collections import deque
# Function to find maximum sum
# of a subsequence satisfying
# the given conditions
def maxResult(arr, k):
# Stores the maximum sum
dp = [0]*len(arr)
# Starting index of
# the subsequence
dp[0] = arr[0]
# Stores the pair of maximum value
# and the index of that value
q = deque([(arr[0], 0)])
# Traverse the array
for i in range(1, len(arr)):
# Increment the first value
# of deque by arr[i] and
# store it in dp[i]
dp[i] = arr[i] + q[0][0]
# Delete all the values which
# are less than dp[i] in deque
while q and q[-1][0] < dp[i]:
q.pop()
# Append the current pair of
# value and index in deque
q.append((dp[i], i))
# If first value of the
# queue is at a distance > K
if i - k == q[0][1]:
q.popleft()
# Return the value at the last index
return dp[-1]
# Driver Code
arr = [10, -5, -2, 4, 0, 3]
K = 3
print(maxResult(arr, K))
17
时间复杂度: O(N)
辅助空间: O(N)