📌  相关文章
📜  最小子序列,连续元素的绝对差之和最大

📅  最后修改于: 2021-05-17 16:32:54             🧑  作者: Mango

给定长度为N的数组arr [] ,其中包含范围为[1,N]的值,任务是找到子序列s 1 ,s 2 ,…,s k ,使得
\\ Sum = \mid s1 - s2 \mid + \mid s2 - s3 \mid +  ...  +  \mid s_{k-1} - s_{k} \mid
最大化。如果多个子序列的总和最大,则打印最小的子序列。

天真的方法:
生成所有长度> = 2的子序列,并计算它们各自的总和。跟踪获得的任何子序列的最大和。在多个子序列的总和最大的情况下,请继续更新最小长度,并保持该子序列的大小。最后打印子序列。
时间复杂度: O(2 N )

高效方法:
有一些关键的观察将有助于我们继续前进:

  1. 当考虑置换中的所有元素时,将获得最大和。
    例如:

    既然我们知道了最大可能的和,我们的目标是在不影响该最大和的情况下最小化子序列的长度。

  2. 对于单调递增或递减的子序列,仅考虑First和Last元素即可达到最大总和,例如:

这样,可以减小子序列的长度而不会影响Max sum

因此,从给定数组中,继续提取单调递增或递减子序列的端点,并通过以下方式将其添加到子序列中:

  • 排列的第一个最后一个元素是默认端点
  • 如果P [i – 1]

    P [i + 1],则元素P [i]单调递增的端点。

  • 如果P [i – 1]> P [i]

    元素P [i]单调递减的端点

    这样获得的子序列将具有最大和和最小长度。

    下面是上述方法的实现:

    C++
    // C++ program to find
    // smallest subsequence
    // with sum of absolute
    // difference of consecutive
    // elements maximized
    #include 
    using namespace std;
      
    // Function to print the smallest
    // subsequence and its sum
    void getSubsequence(vector& arr,
                        int n)
    {
        // Final subsequence
        vector req;
      
        // First element is
        // a default endpoint
        req.push_back(arr[0]);
      
        // Iterating through the array
        for (int i = 1; i < n - 1; i++) {
      
            // Check for monotonically
            // increasing endpoint
            if (arr[i] > arr[i + 1]
                && arr[i] > arr[i - 1])
                req.push_back(arr[i]);
      
            // Check for monotonically
            // decreasing endpoint
            else if (arr[i] < arr[i + 1]
                     && arr[i] < arr[i - 1])
                req.push_back(arr[i]);
        }
      
        // Last element is
        // a default endpoint
        req.push_back(arr[n - 1]);
      
        // Length of final subsequence
        cout << req.size() << endl;
      
        // Print the subsequence
        for (auto x : req)
            cout << x << " ";
    }
      
    // Driver Program
    int main()
    {
        vector arr = { 1, 2, 5, 3,
                            6, 7, 4 };
        int n = arr.size();
        getSubsequence(arr, n);
      
        return 0;
    }


    Java
    // Java program to find smallest
    // subsequence with sum of absolute
    // difference of consecutive
    // elements maximized
    import java.util.*;
      
    class GFG{
      
    // Function to print the smallest
    // subsequence and its sum
    static void getSubsequence(int []arr, int n)
    {
          
        // Final subsequence
        Vector req = new Vector();
      
        // First element is
        // a default endpoint
        req.add(arr[0]);
      
        // Iterating through the array
        for(int i = 1; i < n - 1; i++)
        {
              
           // Check for monotonically
           // increasing endpoint
           if (arr[i] > arr[i + 1] && 
               arr[i] > arr[i - 1])
               req.add(arr[i]);
                 
           // Check for monotonically
           // decreasing endpoint
           else if (arr[i] < arr[i + 1] && 
                    arr[i] < arr[i - 1])
               req.add(arr[i]);
        }
      
        // Last element is
        // a default endpoint
        req.add(arr[n - 1]);
      
        // Length of final subsequence
        System.out.print(req.size() + "\n");
      
        // Print the subsequence
        for(int x : req)
           System.out.print(x + " ");
    }
      
    // Driver code
    public static void main(String[] args)
    {
        int []arr = { 1, 2, 5, 3,
                      6, 7, 4 };
        int n = arr.length;
          
        getSubsequence(arr, n);
    }
    }
      
    // This code is contributed by Amit Katiyar


    Python3
    # Python3 program to find smallest
    # subsequence with sum of absolute
    # difference of consecutive
    # elements maximized
      
    # Function to print the smallest
    # subsequence and its sum
    def getSubsequence(arr, n):
          
        # Final subsequence
        req = []
          
        # First element is
        # a default endpoint
        req.append(arr[0])
          
        # Iterating through the array
        for i in range(1, n - 1):
              
            # Check for monotonically
            # increasing endpoint
            if (arr[i] > arr[i + 1] and
                arr[i] > arr[i - 1]):
                req.append(arr[i])
             
            # Check for monotonically
            # decreasing endpoint
            elif (arr[i] < arr[i + 1] and 
                  arr[i] < arr[i - 1]):
                req.append(arr[i]);
                  
        # Last element is
        # a default endpoint
        req.append(arr[n - 1]);
      
        # Length of final subsequence
        print(len(req))
      
        # Print the subsequence
        for x in req:
            print(x, end = ' ')
      
    # Driver code
    if __name__=='__main__':
          
        arr = [ 1, 2, 5, 3, 6, 7, 4 ]
        n = len(arr)
          
        getSubsequence(arr, n)
      
    # This code is contributed by rutvik_56


    C#
    // C# program to find smallest
    // subsequence with sum of absolute
    // difference of consecutive
    // elements maximized
    using System;
    using System.Collections.Generic;
      
    class GFG{
       
    // Function to print the smallest
    // subsequence and its sum
    static void getSubsequence(int []arr, int n)
    {
           
        // Final subsequence
        List req = new List();
       
        // First element is
        // a default endpoint
        req.Add(arr[0]);
       
        // Iterating through the array
        for(int i = 1; i < n - 1; i++)
        {
               
           // Check for monotonically
           // increasing endpoint
           if (arr[i] > arr[i + 1] && 
               arr[i] > arr[i - 1])
               req.Add(arr[i]);
                  
           // Check for monotonically
           // decreasing endpoint
           else if (arr[i] < arr[i + 1] && 
                    arr[i] < arr[i - 1])
               req.Add(arr[i]);
        }
       
        // Last element is
        // a default endpoint
        req.Add(arr[n - 1]);
       
        // Length of readonly subsequence
        Console.Write(req.Count + "\n");
       
        // Print the subsequence
        foreach(int x in req)
           Console.Write(x + " ");
    }
       
    // Driver code
    public static void Main(String[] args)
    {
        int []arr = { 1, 2, 5, 3,
                      6, 7, 4 };
        int n = arr.Length;
           
        getSubsequence(arr, n);
    }
    }
      
    // This code is contributed by Amit Katiyar


    输出:
    5
    1 5 3 7 4
    

    时间复杂度: O(N)