📜  最大子序列总和,以使三个子序列都不连续

📅  最后修改于: 2021-04-26 18:34:53             🧑  作者: Mango

给定一个正数序列,找到不存在三个连续元素的可形成的最大和。
例子 :

Input: arr[] = {1, 2, 3}
Output: 5
We can't take three of them, so answer is
2 + 3 = 5

Input: arr[] = {3000, 2000, 1000, 3, 10}
Output: 5013 
3000 + 2000 + 3 + 10 = 5013

Input: arr[] = {100, 1000, 100, 1000, 1}
Output: 2101
100 + 1000 + 1000 + 1 = 2101

Input: arr[] = {1, 1, 1, 1, 1}
Output: 4

Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8}
Output: 27

该问题主要是以下问题的扩展。
使得两个元素都不相邻的最大和
我们维护一个辅助数组sum [](与输入数组大小相同)以查找结果。

sum[i] : Stores result for subarray arr[0..i], i.e.,
         maximum possible sum in subarray arr[0..i]
         such that no three elements are consecutive.

sum[0] = arr[0]

// Note : All elements are positive
sum[1] = arr[0] + arr[1]

// We have three cases
// 1) Exclude arr[2], i.e., sum[2] = sum[1]
// 2) Exclude arr[1], i.e., sum[2] = sum[0] + arr[2]
// 3) Exclude arr[0], i.e., sum[2] = arr[1] + arr[2] 
sum[2] = max(sum[1], arr[0] + arr[2], arr[1] + arr[2])

In general,
// We have three cases
// 1) Exclude arr[i],  i.e.,  sum[i] = sum[i-1]
// 2) Exclude arr[i-1], i.e., sum[i] = sum[i-2] + arr[i]
// 3) Exclude arr[i-2], i.e., sum[i-3] + arr[i] + arr[i-1] 
sum[i] = max(sum[i-1], sum[i-2] + arr[i],
             sum[i-3] + arr[i] + arr[i-1])

以下是上述想法的实现。

C++14
// C++ program to find the maximum sum such that
// no three are consecutive
#include 
using namespace std;
   
// Returns maximum subsequence sum such that no three
// elements are consecutive
int maxSumWO3Consec(int arr[], int n)
{
    // Stores result for subarray arr[0..i], i.e.,
    // maximum possible sum in subarray arr[0..i]
    // such that no three elements are consecutive.
    int sum[n];
   
    // Base cases (process first three elements)
    if (n >= 1)
        sum[0] = arr[0];
   
    if (n >= 2)
        sum[1] = arr[0] + arr[1];
   
    if (n > 2)
        sum[2] = max(sum[1], max(arr[1] +
                               arr[2], arr[0] + arr[2]));
   
    // Process rest of the elements
    // We have three cases
    // 1) Exclude arr[i], i.e., sum[i] = sum[i-1]
    // 2) Exclude arr[i-1], i.e., sum[i] = sum[i-2] + arr[i]
    // 3) Exclude arr[i-2], i.e., sum[i-3] + arr[i] + arr[i-1]
    for (int i = 3; i < n; i++)
        sum[i] = max(max(sum[i - 1], sum[i - 2] + arr[i]),
                     arr[i] + arr[i - 1] + sum[i - 3]);
   
    return sum[n - 1];
}
   
// Driver code
int main()
{
    int arr[] = { 100, 1000 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maxSumWO3Consec(arr, n);
    return 0;
}


Java
// java program to find the maximum sum
// such that no three are consecutive
import java.io.*;
 
class GFG {
 
    // Returns maximum subsequence sum such that no three
    // elements are consecutive
    static int maxSumWO3Consec(int arr[], int n)
    {
        // Stores result for subarray arr[0..i], i.e.,
        // maximum possible sum in subarray arr[0..i]
        // such that no three elements are consecutive.
        int sum[] = new int[n];
 
        // Base cases (process first three elements)
        if (n >= 1)
            sum[0] = arr[0];
 
        if (n >= 2)
            sum[1] = arr[0] + arr[1];
 
        if (n > 2)
            sum[2] = Math.max(sum[1], Math.max(arr[1] + arr[2], arr[0] + arr[2]));
 
        // Process rest of the elements
        // We have three cases
        // 1) Exclude arr[i], i.e., sum[i] = sum[i-1]
        // 2) Exclude arr[i-1], i.e., sum[i] = sum[i-2] + arr[i]
        // 3) Exclude arr[i-2], i.e., sum[i-3] + arr[i] + arr[i-1]
        for (int i = 3; i < n; i++)
            sum[i] = Math.max(Math.max(sum[i - 1], sum[i - 2] + arr[i]),
                              arr[i] + arr[i - 1] + sum[i - 3]);
 
        return sum[n - 1];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 100, 1000, 100, 1000, 1 };
        int n = arr.length;
        System.out.println(maxSumWO3Consec(arr, n));
    }
}
 
// This code is contributed by vt_m


Python
# Python program to find the maximum sum such that
# no three are consecutive
 
# Returns maximum subsequence sum such that no three
# elements are consecutive
def maxSumWO3Consec(arr, n):
    # Stores result for subarray arr[0..i], i.e.,
    # maximum possible sum in subarray arr[0..i]
    # such that no three elements are consecutive.
    sum = [0 for k in range(n)]
 
    # Base cases (process first three elements)
     
    if n >= 1 :
        sum[0] = arr[0]
     
    if n >= 2 :
        sum[1] = arr[0] + arr[1]
     
    if n > 2 :
        sum[2] = max(sum[1], max(arr[1] + arr[2], arr[0] + arr[2]))
 
    # Process rest of the elements
    # We have three cases
    # 1) Exclude arr[i], i.e., sum[i] = sum[i-1]
    # 2) Exclude arr[i-1], i.e., sum[i] = sum[i-2] + arr[i]
    # 3) Exclude arr[i-2], i.e., sum[i-3] + arr[i] + arr[i-1]
    for i in range(3, n):
        sum[i] = max(max(sum[i-1], sum[i-2] + arr[i]), arr[i] + arr[i-1] + sum[i-3])
 
    return sum[n-1]
 
# Driver code
arr = [100, 1000, 100, 1000, 1]
n = len(arr)
print maxSumWO3Consec(arr, n)
 
# This code is contributed by Afzal Ansari


C#
// C# program to find the maximum sum
// such that no three are consecutive
using System;
class GFG {
 
    // Returns maximum subsequence
    // sum such that no three
    // elements are consecutive
    static int maxSumWO3Consec(int[] arr,
                               int n)
    {
        // Stores result for subarray
        // arr[0..i], i.e., maximum
        // possible sum in subarray
        // arr[0..i] such that no
        // three elements are consecutive.
        int[] sum = new int[n];
 
        // Base cases (process
        // first three elements)
        if (n >= 1)
            sum[0] = arr[0];
 
        if (n >= 2)
            sum[1] = arr[0] + arr[1];
 
        if (n > 2)
            sum[2] = Math.Max(sum[1], Math.Max(arr[1] + arr[2], arr[0] + arr[2]));
 
        // Process rest of the elements
        // We have three cases
        // 1) Exclude arr[i], i.e.,
        // sum[i] = sum[i-1]
        // 2) Exclude arr[i-1], i.e.,
        // sum[i] = sum[i-2] + arr[i]
        // 3) Exclude arr[i-2], i.e.,
        // sum[i-3] + arr[i] + arr[i-1]
        for (int i = 3; i < n; i++)
            sum[i] = Math.Max(Math.Max(sum[i - 1],
                                       sum[i - 2] + arr[i]),
                              arr[i] + arr[i - 1] + sum[i - 3]);
 
        return sum[n - 1];
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { 100, 1000, 100, 1000, 1 };
        int n = arr.Length;
        Console.Write(maxSumWO3Consec(arr, n));
    }
}
 
// This code is contributed by nitin mittal.


PHP
= 1)
    $sum[0] = $arr[0];
     
    if ($n >= 2)
    $sum[1] = $arr[0] + $arr[1];
     
    if ( $n > 2)
    $sum[2] = max($sum[1], max($arr[1] + $arr[2],
                            $arr[0] + $arr[2]));
 
    // Process rest of the elements
    // We have three cases
    // 1) Exclude arr[i], i.e.,
    // sum[i] = sum[i-1]
    // 2) Exclude arr[i-1], i.e.,
    // sum[i] = sum[i-2] + arr[i]
    // 3) Exclude arr[i-2], i.e.,
    // sum[i-3] + arr[i] + arr[i-1]
    for ($i = 3; $i < $n; $i++)
        $sum[$i] = max(max($sum[$i - 1],
                        $sum[$i - 2] + $arr[$i]),
                        $arr[$i] + $arr[$i - 1] +
                                    $sum[$i - 3]);
 
    return $sum[$n-1];
}
 
// Driver code
$arr = array(100, 1000, 100, 1000, 1);
$n =count($arr);
echo maxSumWO3Consec($arr, $n);
 
// This code is contributed by anuj_67.
?>


Javascript


C++
// C++ program to find the maximum sum such that
// no three are consecutive using recursion.
#include
using namespace std;
 
int arr[] = {100, 1000, 100, 1000, 1};
int sum[10000];
 
// Returns maximum subsequence sum such that no three
// elements are consecutive
int maxSumWO3Consec(int n)
{
    if(sum[n]!=-1)
    return sum[n];
     
    //Base cases (process first three elements)
     
    if(n==0)
    return sum[n] = 0;
     
    if(n==1)
    return sum[n] = arr[0];
     
    if(n==2)
    return sum[n] = arr[1]+arr[0];
     
    // Process rest of the elements
    // We have three cases
    return sum[n] = max(max(maxSumWO3Consec(n-1),
                    maxSumWO3Consec(n-2) + arr[n]),
                    arr[n] + arr[n-1] + maxSumWO3Consec(n-3));
     
     
}
 
// Driver code
int main()
{
     
    int n = sizeof(arr) / sizeof(arr[0]);
    memset(sum,-1,sizeof(sum));
    cout << maxSumWO3Consec(n);
 
// this code is contributed by Kushdeep Mittal
    return 0;
}


Java
// Java program to find the maximum
// sum such that no three are
// consecutive using recursion.
import java.util.Arrays;
 
class GFG
{
     
static int arr[] = {100, 1000, 100, 1000, 1};
static int sum[] = new int[10000];
 
// Returns maximum subsequence
// sum such that no three
// elements are consecutive
static int maxSumWO3Consec(int n)
{
    if(sum[n] != -1)
        return sum[n];
     
    //Base cases (process first three elements)
     
    if(n == 0)
        return sum[n] = 0;
     
    if(n == 1)
        return sum[n] = arr[0];
     
    if(n == 2)
        return sum[n] = arr[1] + arr[0];
     
    // Process rest of the elements
    // We have three cases
    return sum[n] = Math.max(Math.max(maxSumWO3Consec(n - 1),
                    maxSumWO3Consec(n - 2) + arr[n]),
                    arr[n] + arr[n - 1] + maxSumWO3Consec(n - 3));
     
     
}
 
// Driver code
public static void main(String[] args)
{
    int n = arr.length;
        Arrays.fill(sum, -1);
    System.out.println(maxSumWO3Consec(n));
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program to find the maximum
# sum such that no three are consecutive
# using recursion.
arr = [100, 1000, 100, 1000, 1]
sum = [-1] * 10000
 
# Returns maximum subsequence sum such
# that no three elements are consecutive
def maxSumWO3Consec(n) :
 
    if(sum[n] != -1):
        return sum[n]
     
    # 3 Base cases (process first
    # three elements)
    if(n == 0) :
        sum[n] = 0
        return sum[n]
     
    if(n == 1) :
        sum[n] = arr[0]
        return sum[n]
     
    if(n == 2) :
        sum[n] = arr[1] + arr[0]
        return sum[n]
     
    # Process rest of the elements
    # We have three cases
    sum[n] = max(max(maxSumWO3Consec(n - 1),
                     maxSumWO3Consec(n - 2) + arr[n]),
                     arr[n] + arr[n - 1] +
                     maxSumWO3Consec(n - 3))
     
    return sum[n]
 
# Driver code
if __name__ == "__main__" :
 
    n = len(arr)
     
    print(maxSumWO3Consec(n))
 
# This code is contributed by Ryuga


C#
// C# program to find the maximum
// sum such that no three are
// consecutive using recursion.
using System;
 
class GFG
{
 
    static int []arr = {100, 1000,
                        100, 1000, 1};
    static int []sum = new int[10000];
 
    // Returns maximum subsequence
    // sum such that no three
    // elements are consecutive
    static int maxSumWO3Consec(int n)
    {
        if(sum[n] != -1)
            return sum[n];
 
        //Base cases (process first
        // three elements)
        if(n == 0)
            return sum[n] = 0;
 
        if(n == 1)
            return sum[n] = arr[0];
 
        if(n == 2)
            return sum[n] = arr[1] + arr[0];
 
        // Process rest of the elements
        // We have three cases
        return sum[n] = Math.Max(Math.Max(maxSumWO3Consec(n - 1),
                        maxSumWO3Consec(n - 2) + arr[n]),
                        arr[n] + arr[n - 1] + maxSumWO3Consec(n - 3));
 
 
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int n = arr.Length;
        for(int i = 0; i < sum.Length; i++)
            sum[i] = -1;
        Console.WriteLine(maxSumWO3Consec(n));
    }
}
 
// This code is contributed by 29AjayKumar


PHP


输出 :

2101

时间复杂度: O(n)
辅助空间: O(n)
另一种方法:(使用递归)

C++

// C++ program to find the maximum sum such that
// no three are consecutive using recursion.
#include
using namespace std;
 
int arr[] = {100, 1000, 100, 1000, 1};
int sum[10000];
 
// Returns maximum subsequence sum such that no three
// elements are consecutive
int maxSumWO3Consec(int n)
{
    if(sum[n]!=-1)
    return sum[n];
     
    //Base cases (process first three elements)
     
    if(n==0)
    return sum[n] = 0;
     
    if(n==1)
    return sum[n] = arr[0];
     
    if(n==2)
    return sum[n] = arr[1]+arr[0];
     
    // Process rest of the elements
    // We have three cases
    return sum[n] = max(max(maxSumWO3Consec(n-1),
                    maxSumWO3Consec(n-2) + arr[n]),
                    arr[n] + arr[n-1] + maxSumWO3Consec(n-3));
     
     
}
 
// Driver code
int main()
{
     
    int n = sizeof(arr) / sizeof(arr[0]);
    memset(sum,-1,sizeof(sum));
    cout << maxSumWO3Consec(n);
 
// this code is contributed by Kushdeep Mittal
    return 0;
}

Java

// Java program to find the maximum
// sum such that no three are
// consecutive using recursion.
import java.util.Arrays;
 
class GFG
{
     
static int arr[] = {100, 1000, 100, 1000, 1};
static int sum[] = new int[10000];
 
// Returns maximum subsequence
// sum such that no three
// elements are consecutive
static int maxSumWO3Consec(int n)
{
    if(sum[n] != -1)
        return sum[n];
     
    //Base cases (process first three elements)
     
    if(n == 0)
        return sum[n] = 0;
     
    if(n == 1)
        return sum[n] = arr[0];
     
    if(n == 2)
        return sum[n] = arr[1] + arr[0];
     
    // Process rest of the elements
    // We have three cases
    return sum[n] = Math.max(Math.max(maxSumWO3Consec(n - 1),
                    maxSumWO3Consec(n - 2) + arr[n]),
                    arr[n] + arr[n - 1] + maxSumWO3Consec(n - 3));
     
     
}
 
// Driver code
public static void main(String[] args)
{
    int n = arr.length;
        Arrays.fill(sum, -1);
    System.out.println(maxSumWO3Consec(n));
}
}
 
// This code is contributed by Rajput-Ji

Python3

# Python3 program to find the maximum
# sum such that no three are consecutive
# using recursion.
arr = [100, 1000, 100, 1000, 1]
sum = [-1] * 10000
 
# Returns maximum subsequence sum such
# that no three elements are consecutive
def maxSumWO3Consec(n) :
 
    if(sum[n] != -1):
        return sum[n]
     
    # 3 Base cases (process first
    # three elements)
    if(n == 0) :
        sum[n] = 0
        return sum[n]
     
    if(n == 1) :
        sum[n] = arr[0]
        return sum[n]
     
    if(n == 2) :
        sum[n] = arr[1] + arr[0]
        return sum[n]
     
    # Process rest of the elements
    # We have three cases
    sum[n] = max(max(maxSumWO3Consec(n - 1),
                     maxSumWO3Consec(n - 2) + arr[n]),
                     arr[n] + arr[n - 1] +
                     maxSumWO3Consec(n - 3))
     
    return sum[n]
 
# Driver code
if __name__ == "__main__" :
 
    n = len(arr)
     
    print(maxSumWO3Consec(n))
 
# This code is contributed by Ryuga

C#

// C# program to find the maximum
// sum such that no three are
// consecutive using recursion.
using System;
 
class GFG
{
 
    static int []arr = {100, 1000,
                        100, 1000, 1};
    static int []sum = new int[10000];
 
    // Returns maximum subsequence
    // sum such that no three
    // elements are consecutive
    static int maxSumWO3Consec(int n)
    {
        if(sum[n] != -1)
            return sum[n];
 
        //Base cases (process first
        // three elements)
        if(n == 0)
            return sum[n] = 0;
 
        if(n == 1)
            return sum[n] = arr[0];
 
        if(n == 2)
            return sum[n] = arr[1] + arr[0];
 
        // Process rest of the elements
        // We have three cases
        return sum[n] = Math.Max(Math.Max(maxSumWO3Consec(n - 1),
                        maxSumWO3Consec(n - 2) + arr[n]),
                        arr[n] + arr[n - 1] + maxSumWO3Consec(n - 3));
 
 
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int n = arr.Length;
        for(int i = 0; i < sum.Length; i++)
            sum[i] = -1;
        Console.WriteLine(maxSumWO3Consec(n));
    }
}
 
// This code is contributed by 29AjayKumar

的PHP


输出 :

2101