给定长度为N的数组arr [] ,其中包含范围为[1,N]的值,任务是找到子序列s 1 ,s 2 ,…,s k ,使得
被最大化。如果多个子序列的总和最大,则打印最小的子序列。
Input: N = 3, P = {3, 2, 1}
Output: K = 2, S = {3, 1}
Explanation:
Maximum sum possible = 2
Subsequences {3, 2, 1} and {3, 1} achieves that sum.
Hence, the subsequence {3, 1} is considered being of smaller length.
Input: N = 4, P = {1, 3, 4, 2}
Output: K = 3, S = {1, 4, 2}
Explanation:
Maximum sum possible = 5
Subsequences {1, 3, 4, 2} and {1, 4, 2} achieves that sum.
Hence, the subsequence {1, 4, 2} is considered being of smaller length.
天真的方法:
生成所有长度> = 2的子序列,并计算它们各自的总和。跟踪获得的任何子序列的最大和。在多个子序列的总和最大的情况下,请继续更新最小长度,并保持该子序列的大小。最后打印子序列。
时间复杂度: O(2 N )
高效方法:
有一些关键的观察将有助于我们继续前进:
- 当考虑置换中的所有元素时,将获得最大和。
例如:N = 4, P = [1, 3, 4, 2]
Max sum = | 1 – 3 | + | 3 – 4 | + | 4 – 2 | = 2 + 1 + 2 = 5
Here, the length is N and the required subsequence is permutation P itself.既然我们知道了最大可能的和,我们的目标是在不影响该最大和的情况下最小化子序列的长度。
- 对于单调增加或减少的子序列,仅考虑First和Last元素即可达到最大总和,例如:
S = [1, 3, 5, 7]
Max sum = | 1 – 3 | + | 3 – 5 | + | 5 – 7 | = 2 + 2 + 2 = 6, K = 4
Considering only first and last element,
S = [1, 7]
Max sum = | 1 – 7 | = 6, K = 2
这样,可以减小子序列的长度而不会影响Max sum 。
因此,从给定数组中,继续提取单调递增或递减子序列的端点,并通过以下方式将其添加到子序列中:
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)
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。