📜  长度为 k 的最大和子序列

📅  最后修改于: 2021-09-17 06:50:18             🧑  作者: 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 < i) 处存在一些子序列,其中 dp[j][l] + arr[i] 的总和大于其初始值计算值然后更新该值。
然后最后我们将找到 dp[i][k] 的最大值,即对于每个“i”,如果 k 长度的子序列导致的总和比更新所需的 ans 多。

下面是实现代码:

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


Python3
# 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


Javascript


输出:
40

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

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