📜  最长反向双音序列

📅  最后修改于: 2021-05-14 06:31:17             🧑  作者: Mango

给定长度Narr [] ,任务是找到最长的反向双音子序列的长度。如果子序列先减小然后增大,则称为反向双音。
例子:

方法:
此问题是标准最长增加子序列(LIS)问题的变体。使用动态编程构造两个数组lis []lds []来分别存储最长的递增和递减子序列,直到该数组的i索引为止。最后,返回lds [i] + lis [i] – 1的最大值,其中i的范围为0到N-1。
下面是上述方法的实现:

C++
// C++ program to find the
// longest Reverse bitonic
// Subsequence
#include 
using namespace std;
 
// Function to return the length
// of the Longest Reverse Bitonic
// Subsequence in the array
int ReverseBitonic(int arr[], int N)
{
    int i, j;
 
    // Allocate memory for LIS[] and
    // initialize LIS values as 1 for
    // all indexes
    int lds[N];
    for (i = 0; i < N; i++) {
        lds[i] = 1;
    }
 
    // Compute LIS values from left
    // to right for every index
    for (i = 1; i < N; i++) {
        for (j = 0; j < i; j++) {
            if (arr[i] < arr[j]
                && lds[i] < lds[j] + 1) {
                lds[i] = lds[j] + 1;
            }
        }
    }
 
    // Initialize LDS for
    // all indexes as 1
    int lis[N];
    for (i = 0; i < N; i++) {
        lis[i] = 1;
    }
 
    // Compute LDS values for every
    // index from right to left
    for (i = N - 2; i >= 0; i--) {
        for (j = N - 1; j > i; j--) {
            if (arr[i] < arr[j]
                && lis[i] < lis[j] + 1) {
                lis[i] = lis[j] + 1;
            }
        }
    }
 
    // Find the maximum value of
    // lis[i] + lds[i] - 1
    // in the array
    int max = lis[0] + lds[0] - 1;
    for (i = 1; i < N; i++) {
        if (lis[i] + lds[i] - 1 > max) {
            max = lis[i] + lds[i] - 1;
        }
    }
    // Return the maximum
    return max;
}
 
// Driver Program
int main()
{
 
    int arr[] = { 0, 8, 4, 12, 2, 10, 6,
                  14, 1, 9, 5, 13, 3, 11,
                  7, 15 };
    int N = sizeof(arr) / sizeof(arr[0]);
    printf("Length of LBS is %d\n",
           ReverseBitonic(arr, N));
    return 0;
}


Java
// Java program to find the
// longest Reverse bitonic
// Subsequence
import java.io.*;
 
class GFG{
 
// Function to return the length
// of the Longest Reverse Bitonic
// Subsequence in the array
static int ReverseBitonic(int arr[], int N)
{
    int i, j;
 
    // Allocate memory for LIS[] and
    // initialize LIS values as 1 for
    // all indexes
    int[] lds = new int[N];
    for(i = 0; i < N; i++)
    {
        lds[i] = 1;
    }
 
    // Compute LIS values from left
    // to right for every index
    for(i = 1; i < N; i++)
    {
        for(j = 0; j < i; j++)
        {
            if (arr[i] < arr[j] &&
                lds[i] < lds[j] + 1)
            {
                lds[i] = lds[j] + 1;
            }
        }
    }
 
    // Initialize LDS for
    // all indexes as 1
    int[] lis = new int[N];
    for(i = 0; i < N; i++)
    {
        lis[i] = 1;
    }
 
    // Compute LDS values for every
    // index from right to left
    for(i = N - 2; i >= 0; i--)
    {
        for(j = N - 1; j > i; j--)
        {
            if (arr[i] < arr[j] &&
                lis[i] < lis[j] + 1)
            {
                lis[i] = lis[j] + 1;
            }
        }
    }
 
    // Find the maximum value of
    // lis[i] + lds[i] - 1
    // in the array
    int max = lis[0] + lds[0] - 1;
    for(i = 1; i < N; i++)
    {
        if (lis[i] + lds[i] - 1 > max)
        {
            max = lis[i] + lds[i] - 1;
        }
    }
    // Return the maximum
    return max;
}
 
// Driver code
public static void main (String[] args)
{
    int arr[] = { 0, 8, 4, 12,
                  2, 10, 6, 14,
                  1, 9, 5, 13,
                  3, 11, 7, 15 };
                   
    int N = arr.length;
     
    System.out.println("Length of LBS is " +
                      ReverseBitonic(arr, N));
}
}
 
// This code is contributed by jana_sayantan


Python3
# Python3 program to find the
# longest Reverse bitonic
# Subsequence
 
# Function to return the length
# of the Longest Reverse Bitonic
# Subsequence in the array
def ReverseBitonic(arr):
     
    N = len(arr)
 
    # Allocate memory for LIS[] and
    # initialize LIS values as 1
    # for all indexes
    lds = [1 for i in range(N + 1)]
 
    # Compute LIS values from left to right
    for i in range(1, N):
        for j in range(0 , i):
            if ((arr[i] < arr[j]) and
                (lds[i] < lds[j] + 1)):
                lds[i] = lds[j] + 1
 
    # Allocate memory for LDS and
    # initialize LDS values for
    # all indexes
    lis = [1 for i in range(N + 1)]
     
    # Compute LDS values from right to left
    # Loop from n-2 downto 0
    for i in reversed(range(N - 1)):
         
        # Loop from n-1 downto i-1
        for j in reversed(range(i - 1, N)):
            if (arr[i] < arr[j] and
                lis[i] < lis[j] + 1):
                lis[i] = lis[j] + 1
 
    # Return the maximum value of
    # (lis[i] + lds[i] - 1)
    maximum = lis[0] + lds[0] - 1
    for i in range(1, N):
        maximum = max((lis[i] +
                       lds[i] - 1), maximum)
     
    return maximum
 
# Driver code
arr = [ 0, 8, 4, 12,
        2, 10, 6, 14,
        1, 9, 5, 13,
        3, 11, 7, 15 ]
         
print("Length of LBS is", ReverseBitonic(arr))
 
# This code is contributed by grand_master


C#
// C# program to find the
// longest Reverse bitonic
// Subsequence
using System;
 
class GFG{
 
// Function to return the length
// of the Longest Reverse Bitonic
// Subsequence in the array
static int ReverseBitonic(int[] arr, int N)
{
    int i, j;
 
    // Allocate memory for LIS[] and
    // initialize LIS values as 1 for
    // all indexes
    int[] lds = new int[N];
    for(i = 0; i < N; i++)
    {
        lds[i] = 1;
    }
 
    // Compute LIS values from left
    // to right for every index
    for(i = 1; i < N; i++)
    {
        for(j = 0; j < i; j++)
        {
            if (arr[i] < arr[j] &&
                lds[i] < lds[j] + 1)
            {
                lds[i] = lds[j] + 1;
            }
        }
    }
 
    // Initialize LDS for
    // all indexes as 1
    int[] lis = new int[N];
    for(i = 0; i < N; i++)
    {
        lis[i] = 1;
    }
 
    // Compute LDS values for every
    // index from right to left
    for(i = N - 2; i >= 0; i--)
    {
        for(j = N - 1; j > i; j--)
        {
            if (arr[i] < arr[j] &&
                lis[i] < lis[j] + 1)
            {
                lis[i] = lis[j] + 1;
            }
        }
    }
 
    // Find the maximum value of
    // lis[i] + lds[i] - 1
    // in the array
    int max = lis[0] + lds[0] - 1;
    for(i = 1; i < N; i++)
    {
        if (lis[i] + lds[i] - 1 > max)
        {
            max = lis[i] + lds[i] - 1;
        }
    }
     
    // Return the maximum
    return max;
}
 
// Driver code
public static void Main ()
{
    int[] arr = new int[] { 0, 8, 4, 12,
                            2, 10, 6, 14,
                            1, 9, 5, 13,
                            3, 11, 7, 15 };
                     
    int N = arr.Length;
     
    Console.WriteLine("Length of LBS is " +
                     ReverseBitonic(arr, N));
}
}
 
// This code is contributed by sanjoy_62


Javascript


输出:
Length of LBS is 7

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