Maximum Sum Subsequence of length k
Given an array sequence [A1, A2 …An], the task is to find the maximum possible sum of increasing subsequence S of length k such that S1<=S2<=S3………<=Sk.
Examples:
Input :
n = 8 k = 3
A=[8 5 9 10 5 6 21 8]
Output : 40
Possible Increasing subsequence of Length 3 with maximum possible sum is 9 10 21
Input :
n = 9 k = 4
A=[2 5 3 9 15 33 6 18 20]
Output : 62
Possible Increasing subsequence of Length 4 with maximum possible sum is 9 15 18 20
One thing that is clearly visible that it can be easily solved with dynamic programming and this problem is a simple variation of Longest Increasing Subsequence. If you are unknown of how to calculate the longest increasing subsequence then see the implementation going to the link.
Naive Approach:
In the brute force approach, first we will try to find all the subsequences of length k and will check whether they are increasing or not. There could be nCk such sequences in the worst case when all elements are in increasing order. Now we will find the maximum possible sum for such sequences.
Time Complexity would be O((nCk)*n).
Efficient Approach:
We will be using a two-dimensional dp array in which dp[i][l] means that maximum sum subsequence of length l taking array values from 0 to i and the subsequence is ending at index ‘i’. Range of ‘l’ is from 0 to k-1. Using the approach of longer increasing subsequence on the inner loop when j<i we will check if arr[j] < arr[i] for checking if subsequence increasing.
This problem can be divided into its subproblems:
dp[i][1]=arr[i] for length 1 , maximum increasing subsequence is equal to the array value
dp[i][l+1]= max(dp[i][l+1], dp[j][l]+arr[i]) for any length l between 1 to k-1
This means that if for ith position and subsequence of length l+1 , there exists some subsequence at j (j < i) of length l for which sum of dp[j][l] + arr[i] is more than its initial calculated value then update that value.
Then finally we will find the maximum value of dp[i][k] i.e for every ‘i’ if subsequence of k length is causing more sum then update the required ans.
Below is the implementation code:
C++
#include <bits/stdc++.h>
using namespace std;
int MaxIncreasingSub( int arr[], int n, int k)
{
int dp[n][k + 1], ans = -1;
memset (dp, -1, sizeof (dp));
for ( int i = 0; i < n; i++) {
dp[i][1] = arr[i];
}
for ( int i = 1; i < n; i++) {
for ( int j = 0; j < i; j++) {
if (arr[j] < arr[i]) {
for ( int l = 1; l <= k - 1; l++) {
if (dp[j][l] != -1) {
dp[i][l + 1] = max(dp[i][l + 1],
dp[j][l] + arr[i]);
}
}
}
}
}
for ( int i = 0; i < n; i++) {
if (ans < dp[i][k])
ans = dp[i][k];
}
return (ans == -1) ? 0 : ans;
}
int main()
{
int n = 8, k = 3;
int arr[n] = { 8, 5, 9, 10, 5, 6, 21, 8 };
int ans = MaxIncreasingSub(arr, n, k);
cout << ans << "\n" ;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int MaxIncreasingSub( int arr[], int n, int k)
{
int dp[][]= new int [n][k + 1 ], ans = - 1 ;
for ( int i = 0 ; i < n; i++)
for ( int j = 0 ; j < k + 1 ; j++)
dp[i][j]=- 1 ;
for ( int i = 0 ; i < n; i++)
{
dp[i][ 1 ] = arr[i];
}
for ( int i = 1 ; i < n; i++)
{
for ( int j = 0 ; j < i; j++)
{
if (arr[j] < arr[i])
{
for ( int l = 1 ; l <= k - 1 ; l++)
{
if (dp[j][l] != - 1 )
{
dp[i][l + 1 ] = Math.max(dp[i][l + 1 ],
dp[j][l] + arr[i]);
}
}
}
}
}
for ( int i = 0 ; i < n; i++)
{
if (ans < dp[i][k])
ans = dp[i][k];
}
return (ans == - 1 ) ? 0 : ans;
}
public static void main(String args[])
{
int n = 8 , k = 3 ;
int arr[] = { 8 , 5 , 9 , 10 , 5 , 6 , 21 , 8 };
int ans = MaxIncreasingSub(arr, n, k);
System.out.println(ans );
}
}
|
Python3
def MaxIncreasingSub(arr, n, k):
dp = [ - 1 ] * n
ans = - 1
for i in range (n):
dp[i] = [ - 1 ] * (k + 1 )
for i in range (n):
dp[i][ 1 ] = arr[i]
for i in range ( 1 ,n):
for j in range (i):
if arr[j] < arr[i]:
for l in range ( 1 ,k):
if dp[j][l] ! = - 1 :
dp[i][l + 1 ] = max (dp[i][l + 1 ],
dp[j][l] + arr[i])
for i in range (n):
if ans < dp[i][k]:
ans = dp[i][k]
return ( 0 if ans = = - 1 else ans)
if __name__ = = "__main__" :
n, k = 8 , 3
arr = [ 8 , 5 , 9 , 10 , 5 , 6 , 21 , 8 ]
ans = MaxIncreasingSub(arr, n, k)
print (ans)
|
C#
using System;
class GFG
{
static int MaxIncreasingSub( int []arr, int n, int k)
{
int [,]dp= new int [n, k + 1];
int ans = -1;
for ( int i = 0; i < n; i++)
for ( int j = 0; j < k + 1; j++)
dp[i, j]=-1;
for ( int i = 0; i < n; i++)
{
dp[i, 1] = arr[i];
}
for ( int i = 1; i < n; i++)
{
for ( int j = 0; j < i; j++)
{
if (arr[j] < arr[i])
{
for ( int l = 1; l <= k - 1; l++)
{
if (dp[j, l] != -1)
{
dp[i, l + 1] = Math.Max(dp[i, l + 1],
dp[j, l] + arr[i]);
}
}
}
}
}
for ( int i = 0; i < n; i++)
{
if (ans < dp[i, k])
ans = dp[i, k];
}
return (ans == -1) ? 0 : ans;
}
public static void Main(String []args)
{
int n = 8, k = 3;
int []arr = { 8, 5, 9, 10, 5, 6, 21, 8 };
int ans = MaxIncreasingSub(arr, n, k);
Console.WriteLine(ans );
}
}
|
Javascript
<script>
function MaxIncreasingSub(arr, n, k)
{
let dp = new Array(n);
for (let i = 0; i < dp.length; i++)
{
dp[i] = new Array(2);
}
let ans = -1;
for (let i = 0; i < n; i++)
for (let j = 0; j < k + 1; j++)
dp[i][j] = -1;
for (let i = 0; i < n; i++)
{
dp[i][1] = arr[i];
}
for (let i = 1; i < n; i++)
{
for (let j = 0; j < i; j++)
{
if (arr[j] < arr[i])
{
for (let l = 1; l <= k - 1; l++)
{
if (dp[j][l] != -1)
{
dp[i][l + 1] = Math.max(dp[i][l + 1],
dp[j][l] +
arr[i]);
}
}
}
}
}
for (let i = 0; i < n; i++)
{
if (ans < dp[i][k])
ans = dp[i][k];
}
return (ans == -1) ? 0 : ans;
}
let n = 8, k = 3;
let arr = [ 8, 5, 9, 10, 5, 6, 21, 8 ];
let ans = MaxIncreasingSub(arr, n, k);
document.write(ans);
</script>
|
Time complexity: O(n^2*k)
Space complexity: O(n^2)
Last Updated :
01 Sep, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...