给定一个由正数组成的数组 arr[] ,找到一个子序列的最大和,约束条件是序列中没有 2 个数字应该在数组中相邻,其中假设最后一个元素和第一个元素相邻。
例子:
Input: arr[] = {3, 5, 3}
Output: 5
Explanation:
We cannot take the first and last elements because they are considered to be adjacent, hence the output is 5.
Input arr[] = {1, 223, 41, 4, 414, 5, 16}
Output: 653
Explanation:
Taking elements form the index 1, 4 and 6 we get the maximum sum as 653.
方法:思路是使用Memorization算法来解决上面提到的问题。最重要的观察是第一个和最后一个元素永远不能一起选择。所以,我们可以把问题分成两部分:
- 我们可以从索引0 到数组大小的最大总和– 2
- 我们可以从索引1 到数组大小得到的最大总和– 1
答案将是这两个和的最大值,可以使用Dynamic Programming解决。
下面是上述方法的实现:
C++
// C++ program to find maximum sum
// in circular array such that
// no two elements are adjacent
#include
using namespace std;
// Store the maximum possible at each index
vector dp;
int maxSum(int i, vector& subarr)
{
// When i exceeds the index of the
// last element simply return 0
if (i >= subarr.size())
return 0;
// If the value has already been calculated,
// directly return it from the dp array
if (dp[i] != -1)
return dp[i];
// The next states are don't take
// this element and go to (i + 1)th state
// else take this element
// and go to (i + 2)th state
return dp[i]
= max(maxSum(i + 1, subarr),
subarr[i]
+ maxSum(i + 2, subarr));
}
// function to find the max value
int Func(vector arr)
{
vector subarr = arr;
// subarr contains elements
// from 0 to arr.size() - 2
subarr.pop_back();
// Initializing all the values with -1
dp.resize(subarr.size(), -1);
// Calculating maximum possible
// sum for first case
int max1 = maxSum(0, subarr);
subarr = arr;
// subarr contains elements
// from 1 to arr.size() - 1
subarr.erase(subarr.begin());
dp.clear();
// Re-initializing all values with -1
dp.resize(subarr.size(), -1);
// Calculating maximum possible
// sum for second case
int max2 = maxSum(0, subarr);
// Printing the maximum between them
cout << max(max1, max2) << endl;
}
// Driver code
int main()
{
vector arr = { 1, 2, 3, 1 };
Func(arr);
return 0;
}
Java
// Java program to find maximum sum
// in circular array such that
// no two elements are adjacent
import java.util.*;
class GFG{
// Store the maximum
// possible at each index
static Vector dp =
new Vector<>();
static int maxSum(int i,
Vector subarr)
{
// When i exceeds the index of the
// last element simply return 0
if (i >= subarr.size())
return 0;
// If the value has already
// been calculated, directly
// return it from the dp array
if (dp.get(i) != -1)
return dp.get(i);
// The next states are don't take
// this element and go to (i + 1)th state
// else take this element
// and go to (i + 2)th state
dp.add(i, Math.max(maxSum(i + 1, subarr),
subarr.get(i) +
maxSum(i + 2, subarr)));
return dp.get(i);
}
// function to find the max value
static void Func(Vector arr)
{
Vector subarr =
new Vector<>();
subarr.addAll(arr);
// subarr contains elements
// from 0 to arr.size() - 2
subarr.remove(subarr.size() - 1);
// Initializing all the values with -1
dp.setSize(subarr.size());
Collections.fill(dp, -1);
// Calculating maximum possible
// sum for first case
int max1 = maxSum(0, subarr);
subarr = arr;
// subarr contains elements
// from 1 to arr.size() - 1
subarr.remove(0);
dp.clear();
// Re-initializing all values with -1
dp.setSize(subarr.size());
Collections.fill(dp, -1);
// Calculating maximum possible
// sum for second case
int max2 = maxSum(0, subarr);
// Printing the maximum between them
System.out.print(Math.max(max1, max2) + "\n");
}
// Driver code
public static void main(String[] args)
{
Vector arr =new Vector<>();
arr.add(1);
arr.add(2);
arr.add(3);
arr.add(1);
Func(arr);
}
// This code is contributed by gauravrajput1
Python3
# Python3 program to find maximum sum
# in circular array such that
# no two elements are adjacent
# Store the maximum possible at each index
dp = []
def maxSum(i, subarr):
# When i exceeds the index of the
# last element simply return 0
if (i >= len(subarr)):
return 0
# If the value has already been
# calculated, directly return
# it from the dp array
if (dp[i] != -1):
return dp[i]
# The next states are don't take
# this element and go to (i + 1)th state
# else take this element
# and go to (i + 2)th state
dp[i] = max(maxSum(i + 1, subarr),
subarr[i] +
maxSum(i + 2, subarr))
return dp[i]
# function to find the max value
def Func(arr):
subarr = arr
# subarr contains elements
# from 0 to arr.size() - 2
subarr.pop()
global dp
# Initializing all the values with -1
dp= [-1] * (len(subarr))
# Calculating maximum possible
# sum for first case
max1 = maxSum(0, subarr)
subarr = arr
# subarr contains elements
# from 1 to arr.size() - 1
subarr = subarr[:]
del dp
# Re-initializing all values with -1
dp = [-1] * (len(subarr))
# Calculating maximum possible
# sum for second case
max2 = maxSum(0, subarr)
# Printing the maximum between them
print(max(max1, max2))
# Driver code
if __name__ == "__main__":
arr = [1, 2, 3, 1]
Func(arr)
# This code is contributed by Chitranayal
Javascript
输出:
4
时间复杂度: O(N)
辅助空间复杂度: O(N)
类似文章:圆形数组中的最大和,使得没有两个元素相邻
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。