📌  相关文章
📜  最大和交替子序列

📅  最后修改于: 2021-05-08 16:37:33             🧑  作者: Mango

给定一个数组,任务是找到从第一个元素开始的最大和交替子序列的和。在这里,交替序列是指先减小,然后增大,然后减小,…。例如10、5、14、3是交替序列。

请注意,此处的反向类型(递增–递减–递增-…)在此不视为交替。

例子:

Input :  arr[] = {4, 3, 8, 5, 3, 8}  
Output :  28
Explanation:
The alternating subsequence (starting with first element) 
that has above maximum sum is {4, 3, 8, 5, 8}

Input : arr[] = {4, 8, 2, 5, 6, 8} 
Output :  14
The alternating subsequence (starting with first element) 
that has above maximum sum is {4, 2, 8}

此问题类似于最长增加子序列(LIS)问题。可以使用动态编程解决。

Create two empty array that store result of maximum
sum  of alternate sub-sequence
inc[] : inc[i] stores results of maximum sum alternating
        subsequence ending with arr[i] such that arr[i]
        is greater than previous element of the subsequence 
dec[] : dec[i] stores results of maximum sum alternating
        subsequence ending with arr[i] such that arr[i]
        is less than previous element of the subsequence 

Include first element of 'arr' in both inc[] and dec[] 
inc[0] = dec[0] = arr[0]

// Maintain a flag i.e. it will makes the greater
// elements count only if the first decreasing element
// is counted.
flag  = 0 

Traversal two loops
  i goes from 1 to  n-1 
    j goes 0 to i-1
      IF arr[j] > arr[i]
        dec[i] = max(dec[i], inc[j] + arr[i])
    
        // Denotes first decreasing is found
        flag = 1 
  
      ELSE IF arr[j] < arr[i] && flag == 1 
        inc[i] = max(inc[i], dec[j]+arr[i]);
     
Final Last Find maximum value inc[] and dec[] .

以下是上述想法的实现。

C/C++
// C++ program to find sum of maximum
// sum alternating sequence starting with
// first element.
#include
using namespace std;
  
// Return sum of maximum sum alternating
// sequence starting with arr[0] and is first
// decreasing.
int maxAlternateSum(int arr[], int n)
{
    if (n == 1)
        return arr[0];
  
   // create two empty array that store result of
   // maximum sum of alternate sub-sequence
  
    // stores sum of decreasing and increasing
    // sub-sequence
    int dec[n];
    memset(dec, 0, sizeof(dec));
  
    // store sum of increasing and decreasing sun-sequence
    int inc[n];
    memset(inc, 0, sizeof(inc));
  
    // As per question, first element must be part
    // of solution.
    dec[0] = inc[0] = arr[0];
  
    int flag = 0 ;
  
    // Traverse remaining elements of array
    for (int i=1; i arr[i])
            {
                dec[i] = max(dec[i], inc[j]+arr[i]);
  
                // Revert the flag , if first decreasing
                // is found
                flag = 1;
            }
  
            // If next element is greater but flag should be 1
            // i.e. this element should be counted after the
            // first decreasing element gets counted
            else if (arr[j] < arr[i] && flag == 1)
  
                // If current sub-sequence is increasing
                // then update inc[i]
                inc[i] = max(inc[i], dec[j]+arr[i]);
        }
    }
  
    // find maximum sum in b/w inc[] and dec[]
    int result = INT_MIN;
    for (int i = 0 ; i < n; i++)
    {
        if (result < inc[i])
            result = inc[i];
        if (result < dec[i])
            result = dec[i];
    }
  
    // return maximum sum alternate sun-sequence
    return result;
}
  
//Driver program
int main()
{
    int arr[]= {8, 2, 3, 5, 7, 9, 10};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "Maximum sum = "
         << maxAlternateSum(arr , n ) << endl;
    return 0;
}


Java
// Java program to find sum of maximum
// sum alternating sequence starting with
// first element.
  
public class GFG 
{
    // Return sum of maximum sum alternating
    // sequence starting with arr[0] and is first
    // decreasing.
    static int maxAlternateSum(int arr[], int n)
    {
        if (n == 1)
            return arr[0];
       
       // create two empty array that store result of
       // maximum sum of alternate sub-sequence
       
        // stores sum of decreasing and increasing
        // sub-sequence
        int dec[] = new int[n];
          
       
        // store sum of increasing and decreasing sun-sequence
        int inc[] = new int[n];
       
        // As per question, first element must be part
        // of solution.
        dec[0] = inc[0] = arr[0];
       
        int flag = 0 ;
       
        // Traverse remaining elements of array
        for (int i=1; i arr[i])
                {
                    dec[i] = Math.max(dec[i], inc[j]+arr[i]);
       
                    // Revert the flag , if first decreasing
                    // is found
                    flag = 1;
                }
       
                // If next element is greater but flag should be 1
                // i.e. this element should be counted after the
                // first decreasing element gets counted
                else if (arr[j] < arr[i] && flag == 1)
       
                    // If current sub-sequence is increasing
                    // then update inc[i]
                    inc[i] = Math.max(inc[i], dec[j]+arr[i]);
            }
        }
       
        // find maximum sum in b/w inc[] and dec[]
        int result = Integer.MIN_VALUE;
        for (int i = 0 ; i < n; i++)
        {
            if (result < inc[i])
                result = inc[i];
            if (result < dec[i])
                result = dec[i];
        }
       
        // return maximum sum alternate sun-sequence
        return result;
    }
      
    // Driver Method
    public static void main(String[] args)
    {
        int arr[]= {8, 2, 3, 5, 7, 9, 10};
        System.out.println("Maximum sum = " +
                  maxAlternateSum(arr , arr.length));
    }
}


Python3
# Python3 program to find sum of maximum
# sum alternating sequence starting with
# first element.
  
# Return sum of maximum sum alternating
# sequence starting with arr[0] and is 
# first decreasing.
def maxAlternateSum(arr, n):
  
    if (n == 1):
        return arr[0]
  
    # Create two empty array that
    # store result of maximum sum
    # of alternate sub-sequence
  
    # Stores sum of decreasing and 
    # increasing sub-sequence
    dec = [0 for i in range(n + 1)]
  
    # store sum of increasing and
    # decreasing sun-sequence
    inc = [0 for i in range(n + 1)]
  
    # As per question, first element 
    # must be part of solution.
    dec[0] = inc[0] = arr[0]
  
    flag = 0
  
    # Traverse remaining elements of array
    for i in range(1, n):
      
        for j in range(i):
          
            # IF current sub-sequence is decreasing the
            # update dec[j] if needed. dec[i] by current
            # inc[j] + arr[i]
            if (arr[j] > arr[i]):
              
                dec[i] = max(dec[i], inc[j] + arr[i])
  
                # Revert the flag, if first 
                # decreasing is found
                flag = 1
  
            # If next element is greater but flag should be 1
            # i.e. this element should be counted after the
            # first decreasing element gets counted
            elif (arr[j] < arr[i] and flag == 1):
  
                # If current sub-sequence is 
                # increasing then update inc[i]
                inc[i] = max(inc[i], dec[j] + arr[i])
  
    # Find maximum sum in b/w inc[] and dec[]
    result = -2147483648
    for i in range(n):
      
        if (result < inc[i]):
            result = inc[i]
        if (result < dec[i]):
            result = dec[i]
  
    # Return maximum sum
    # alternate sun-sequence
    return result
  
# Driver program
arr = [8, 2, 3, 5, 7, 9, 10]
n = len(arr)
print("Maximum sum = ",
       maxAlternateSum(arr , n ))
         
# This code is contributed by Anant Agarwal.


C#
// C# program to find sum of maximum
// sum alternating sequence starting with
// first element.
using System;
class GFG {
      
    // Return sum of maximum 
    // sum alternating
    // sequence starting with 
    // arr[0] and is first
    // decreasing.
    static int maxAlternateSum(int []arr, int n)
    {
        if (n == 1)
            return arr[0];
      
        // create two empty array that 
        // store result of maximum sum 
        // of alternate sub-sequence
        // stores sum of decreasing 
        // and increasing sub-sequence
        int []dec = new int[n];
          
        // store sum of increasing and
        // decreasing sun-sequence
        int []inc = new int[n];
      
        // As per question, first 
        // element must be part
        // of solution.
        dec[0] = inc[0] = arr[0];
      
        int flag = 0 ;
      
        // Traverse remaining elements of array
        for (int i = 1; i < n; i++)
        {
            for (int j = 0; j < i; j++)
            {
                  
                // IF current sub-sequence
                // is decreasing the
                // update dec[j] if needed.
                // dec[i] by current
                // inc[j] + arr[i]
                if (arr[j] > arr[i])
                {
                    dec[i] = Math.Max(dec[i], 
                             inc[j] + arr[i]);
      
                    // Revert the flag , if
                    // first decreasing
                    // is found
                    flag = 1;
                }
      
                // If next element is greater
                // but flag should be 1
                // i.e. this element should 
                // be counted after the
                // first decreasing element
                // gets counted
                else if (arr[j] < arr[i] && flag == 1)
      
                    // If current sub-sequence
                    // is increasing then update
                    // inc[i]
                    inc[i] = Math.Max(inc[i], 
                             dec[j] + arr[i]);
            }
        }
      
        // find maximum sum in b/w
        // inc[] and dec[]
        int result = int.MinValue;
        for (int i = 0 ; i < n; i++)
        {
            if (result < inc[i])
                result = inc[i];
            if (result < dec[i])
                result = dec[i];
        }
      
        // return maximum sum 
        // alternate sun-sequence
        return result;
    }
      
    // Driver Method
    public static void Main()
    {
        int []arr= {8, 2, 3, 5, 7, 9, 10};
        Console.Write("Maximum sum = " +
                maxAlternateSum(arr , arr.Length));
    }
}
  
// This code is contributed by Nitin Mittal.


PHP
 $arr[$i]) 
            { 
                $dec[$i] = max($dec[$i], $inc[$j] + 
                                         $arr[$i]); 
  
                // Revert the flag , if first 
                // decreasing is found 
                $flag = 1; 
            } 
  
            // If next element is greater but flag 
            // should be 1 i.e. this element should 
            // be counted after the first decreasing
            // element gets counted 
            else if ($arr[$j] < $arr[$i] && $flag == 1) 
  
                // If current sub-sequence is increasing 
                // then update inc[i] 
                $inc[$i] = max($inc[$i], $dec[$j] + 
                                         $arr[$i]); 
        } 
    } 
  
    // find maximum sum in b/w inc[] and dec[] 
    $result = -(PHP_INT_MAX - 1); 
    for ($i = 0 ; $i < $n; $i++) 
    { 
        if ($result < $inc[$i]) 
            $result = $inc[$i]; 
        if ($result < $dec[$i]) 
            $result = $dec[$i]; 
    } 
  
    // return maximum sum alternate sun-sequence 
    return $result; 
} 
  
// Driver Code 
$arr = array(8, 2, 3, 5, 7, 9, 10); 
$n = sizeof($arr); 
echo "Maximum sum = ",
      maxAlternateSum($arr, $n );
  
// This code is contributed by Ryuga
?>


输出:

Maximum sum = 25

时间复杂度: O(n 2 )
辅助空间: O(n)