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

📅  最后修改于: 2021-09-17 16:11:22             🧑  作者: 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++ 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
?>


Javascript


输出:

Maximum sum = 25

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程