📜  长度k的最大和子序列

📅  最后修改于: 2021-04-29 05:04:49             🧑  作者: Mango

给定一个数组序列[A 1 ,A 2 …A n ],任务是找到长度为k的递增子序列S的最大可能和,以使S 1 <= S 2 <= S 3 ………<= S k

例子:

显而易见的一件事是,可以通过动态编程轻松解决该问题,而这个问题是“最长增加子序列”的简单变体。如果您不知道如何计算最长的递增子序列,请参阅链接中的实现。

天真的方法:
在蛮力方法中,首先我们将尝试找到所有长度为k的子序列,并检查它们是否在增加。当所有元素都按升序排列时,在最坏的情况下可能会有n C k个这样的序列。现在我们将找到此类序列的最大可能和。
时间复杂度将为O(( n C k )* n)。

高效方法:
我们将使用二维dp数组,其中dp [i] [l]表示长度为l的最大和子序列取数组值从0到i,并且该子序列以索引’i’结尾。 “ l”的范围是从0到k-1。当j 此问题可分为以下子问题:

这意味着如果对于第i个位置和长度为l + 1的子序列,在长度为l的j(j 然后,如果k长度的子序列引起的和大于更新所需的ans,则最终我们将找到dp [i] [k]的最大值,即每个“ i”。

下面是实现代码:

C++
/*C++ program to calculate the maximum sum of 
increasing subsequence of length k*/
#include 
using namespace std;
int MaxIncreasingSub(int arr[], int n, int k)
{
    // In the implementation dp[n][k] represents
    // maximum sum subsequence of length k and the
    // subsequence is ending at index n.
    int dp[n][k + 1], ans = -1;
  
    // Initializing whole multidimensional 
    // dp array with value -1
    memset(dp, -1, sizeof(dp));
  
    // For each ith position increasing subsequence
    // of length 1 is equal to that array ith value
    // so initializing dp[i][1] with that array value
    for (int i = 0; i < n; i++) {
        dp[i][1] = arr[i];
    }
  
    // Starting from 1st index as we have calculated
    // for 0th index. Computing optimized dp values 
    // in bottom-up manner
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
  
            // check for increasing subsequence
            if (arr[j] < arr[i]) {
                for (int l = 1; l <= k - 1; l++) {
  
                    // Proceed if value is pre calculated
                    if (dp[j][l] != -1) {
  
                        // Check for all the subsequences 
                        // ending at any j


Java
/*Java program to calculate the maximum sum of 
increasing subsequence of length k*/
import java.util.*;
  
class GFG
{
      
static int MaxIncreasingSub(int arr[], int n, int k) 
{ 
    // In the implementation dp[n][k] represents 
    // maximum sum subsequence of length k and the 
    // subsequence is ending at index n. 
    int dp[][]=new int[n][k + 1], ans = -1; 
  
    // Initializing whole multidimensional 
    // dp array with value -1 
    for(int i = 0; i < n; i++)
        for(int j = 0; j < k + 1; j++)
            dp[i][j]=-1;
  
    // For each ith position increasing subsequence 
    // of length 1 is equal to that array ith value 
    // so initializing dp[i][1] with that array value 
    for (int i = 0; i < n; i++) 
    { 
        dp[i][1] = arr[i]; 
    } 
  
    // Starting from 1st index as we have calculated 
    // for 0th index. Computing optimized dp values 
    // in bottom-up manner 
    for (int i = 1; i < n; i++) 
    { 
        for (int j = 0; j < i; j++) 
        { 
  
            // check for increasing subsequence 
            if (arr[j] < arr[i]) 
            { 
                for (int l = 1; l <= k - 1; l++) 
                { 
  
                    // Proceed if value is pre calculated 
                    if (dp[j][l] != -1)
                    { 
  
                        // Check for all the subsequences 
                        // ending at any j


Python 3
# Python program to calculate the maximum sum
# of increasing subsequence of length k
  
def MaxIncreasingSub(arr, n, k):
      
    # In the implementation dp[n][k] represents 
    # maximum sum subsequence of length k and the 
    # subsequence is ending at index n.
    dp = [-1]*n
    ans = -1
  
    # Initializing whole multidimensional
    # dp array with value - 1
    for i in range(n):
        dp[i] = [-1]*(k+1)
  
    # For each ith position increasing subsequence
    # of length 1 is equal to that array ith value
    # so initializing dp[i][1] with that array value
    for i in range(n):
        dp[i][1] = arr[i]
      
    # Starting from 1st index as we have calculated
    # for 0th index. Computing optimized dp values
    # in bottom-up manner
    for i in range(1,n):
        for j in range(i):
              
            # check for increasing subsequence
            if arr[j] < arr[i]:
                for l in range(1,k):
  
                    # Proceed if value is pre calculated
                    if dp[j][l] != -1:
                          
                        # Check for all the subsequences
                        # ending at any j < i and try including
                        # element at index i in them for
                        # some length l. Update the maximum
                        # value for every length.
                        dp[i][l+1] = max(dp[i][l+1],
                                        dp[j][l] + arr[i])
      
    # The final result would be the maximum 
    # value of dp[i][k] for all different i.
    for i in range(n):
        if ans < dp[i][k]:
            ans = dp[i][k]
      
    # When no subsequence of length k is
    # possible sum would be considered zero
    return (0 if ans == -1 else ans)
  
# Driver Code
if __name__ == "__main__":
  
    n, k = 8, 3
    arr = [8, 5, 9, 10, 5, 6, 21, 8]
    ans = MaxIncreasingSub(arr, n, k)
    print(ans)
  
# This code is contributed by
# sanjeev2552


C#
/*C# program to calculate the maximum sum of 
increasing subsequence of length k*/
using System;
  
class GFG
{
      
static int MaxIncreasingSub(int []arr, int n, int k) 
{ 
    // In the implementation dp[n,k] represents 
    // maximum sum subsequence of length k and the 
    // subsequence is ending at index n. 
    int [,]dp=new int[n, k + 1];
    int ans = -1; 
  
    // Initializing whole multidimensional 
    // dp array with value -1 
    for(int i = 0; i < n; i++)
        for(int j = 0; j < k + 1; j++)
            dp[i, j]=-1;
  
    // For each ith position increasing subsequence 
    // of length 1 is equal to that array ith value 
    // so initializing dp[i,1] with that array value 
    for (int i = 0; i < n; i++) 
    { 
        dp[i, 1] = arr[i]; 
    } 
  
    // Starting from 1st index as we have calculated 
    // for 0th index. Computing optimized dp values 
    // in bottom-up manner 
    for (int i = 1; i < n; i++) 
    { 
        for (int j = 0; j < i; j++) 
        { 
  
            // check for increasing subsequence 
            if (arr[j] < arr[i]) 
            { 
                for (int l = 1; l <= k - 1; l++) 
                { 
  
                    // Proceed if value is pre calculated 
                    if (dp[j, l] != -1)
                    { 
  
                        // Check for all the subsequences 
                        // ending at any j


输出:
40

时间复杂度: O(n ^ 2 * k)
空间复杂度: O(n ^ 2)