给定一个长度为 N 的整数数组 ‘arr’ 和一个整数 ‘k’,选择一些不重叠的子数组,使得每个子数组的长度至多为‘k’,没有两个子数组相邻并且所有子数组的总和所选子阵列的元素最大。
例子:
Input : arr[] = {-1, 2, -3, 4, 5}, k = 2
Output : 11
Sub-arrays that maximizes sum will be {{2}, {4, 5}}.
Thus, the answer will be 2+4+5 = 11.
Input :arr[] = {1, 1, 1, 1, 1}, k = 1
Output : 3
朴素的方法:一种简单的方法是递归地生成满足上述条件的元素的所有可能子集,并找到总和最大的子集。
时间复杂度:O(2 N )
高效的方法:更好的方法是使用动态规划。
假设我们处于索引“i”处。
让dp[i]定义为满足上述条件的子数组{i,n-1}的所有可能子集的元素的最大和。
我们将有“K+1”可能的选择,即
- 拒绝“i”并求解“i+1”。
- 选择子数组 {i} 并求解 ‘i+2’
- 选择子数组 {i, i+1} 并求解 ‘i+3’
因此,递推关系将是:
dp[i] = max(dp[i+1], arr[i]+dp[i+2], arr[i]+arr[i+1]+dp[i+3],
...arr[i]+arr[i+1]+arr[i+2]...+arr[i+k-1] + dp[i+k+1])
下面是上述方法的实现:
C++
// C++ program to implement above approach
#include
#define maxLen 10
using namespace std;
// Variable to store states of dp
int dp[maxLen];
// Variable to check if a given state has been solved
bool visit[maxLen];
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
int maxSum(int arr[], int i, int n, int k)
{
// Base case
if (i >= n)
return 0;
// To check if a state has been solved
if (visit[i])
return dp[i];
visit[i] = 1;
// Variable to store
// prefix sum for sub-array
// {i, j}
int tot = 0;
dp[i] = maxSum(arr, i + 1, n, k);
// Required recurrence relation
for (int j = i; j < i + k and j < n; j++) {
tot += arr[j];
dp[i] = max(dp[i], tot +
maxSum(arr, j + 2, n, k));
}
// Returning the value
return dp[i];
}
// Driver code
int main()
{
// Input array
int arr[] = { -1, 2, -3, 4, 5 };
int k = 2;
int n = sizeof(arr) / sizeof(int);
cout << maxSum(arr, 0, n, k);
return 0;
}
Java
// Java program to implement above approach
import java.io.*;
class GFG
{
static int maxLen = 10;
// Variable to store states of dp
static int dp[] = new int[maxLen];
// Variable to check
// if a given state has been solved
static boolean []visit = new boolean[maxLen];
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
static int maxSum(int arr[], int i,
int n, int k)
{
// Base case
if (i >= n)
return 0;
// To check if a state has been solved
if (visit[i])
return dp[i];
visit[i] = true;
// Variable to store
// prefix sum for sub-array
// {i, j}
int tot = 0;
dp[i] = maxSum(arr, i + 1, n, k);
// Required recurrence relation
for (int j = i; j < (i + k) &&
(j < n); j++)
{
tot += arr[j];
dp[i] = Math.max(dp[i], tot +
maxSum(arr, j + 2, n, k));
}
// Returning the value
return dp[i];
}
// Driver code
public static void main (String[] args)
{
// Input array
int arr[] = { -1, 2, -3, 4, 5 };
int k = 2;
int n = arr.length;
System.out.println(maxSum(arr, 0, n, k));
}
}
// This code is contributed by ajit.
Python3
# Python3 program to implement above approach
maxLen = 10
# Variable to store states of dp
dp = [0]*maxLen;
# Variable to check if a given state has been solved
visit = [0]*maxLen;
# Function to find the maximum sum subsequence
# such that no two elements are adjacent
def maxSum(arr, i, n, k) :
# Base case
if (i >= n) :
return 0;
# To check if a state has been solved
if (visit[i]) :
return dp[i];
visit[i] = 1;
# Variable to store
# prefix sum for sub-array
# {i, j}
tot = 0;
dp[i] = maxSum(arr, i + 1, n, k);
# Required recurrence relation
j = i
while (j < i + k and j < n) :
tot += arr[j];
dp[i] = max(dp[i], tot +
maxSum(arr, j + 2, n, k));
j += 1
# Returning the value
return dp[i];
# Driver code
if __name__ == "__main__" :
# Input array
arr = [ -1, 2, -3, 4, 5 ];
k = 2;
n = len(arr);
print(maxSum(arr, 0, n, k));
# This code is contributed by AnkitRai01
C#
// C# program to implement above approach
using System;
class GFG
{
static int maxLen = 10;
// Variable to store states of dp
static int []dp = new int[maxLen];
// Variable to check
// if a given state has been solved
static bool []visit = new bool[maxLen];
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
static int maxSum(int []arr, int i,
int n, int k)
{
// Base case
if (i >= n)
return 0;
// To check if a state has been solved
if (visit[i])
return dp[i];
visit[i] = true;
// Variable to store
// prefix sum for sub-array
// {i, j}
int tot = 0;
dp[i] = maxSum(arr, i + 1, n, k);
// Required recurrence relation
for (int j = i; j < (i + k) &&
(j < n); j++)
{
tot += arr[j];
dp[i] = Math.Max(dp[i], tot +
maxSum(arr, j + 2, n, k));
}
// Returning the value
return dp[i];
}
// Driver code
static public void Main ()
{
// Input array
int []arr = { -1, 2, -3, 4, 5 };
int k = 2;
int n = arr.Length;
Console.WriteLine (maxSum(arr, 0, n, k));
}
}
// This code is contributed by ajit.
Javascript
输出:
11
时间复杂度: O(n*k)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。