# Longest subsequence with non negative prefix sum at each position

• Difficulty Level : Hard
• Last Updated : 28 Jul, 2021

Given an array arr[] consisting of N integers, the task is to find the longest subsequence such that the prefix sum at each position of the subsequence is non-negative.

Examples:

Input: arr[] = {4, -4, 1, -3, 1, -3}
Output: 5
Explanation:
Consider the subsequence as {4, 1, -3, 1, -3}. Now, the prefix sum of the chosen subsequence is {4, 5, 2, 3, 0}. Since, the prefix sum is non-negative at every possible index. Therefore, this subsequence is of maximum length having length 5.

Input: arr[] = {1, 3, 5, 7}
Output: 4

Naive Approach: The simplest approach to solve this problem is to generate all possible subsequences of the given array and print the length of that subsequence that has a non-negative prefix sum at each position and is of maximum length.

Time Complexity: O(2N)
Auxiliary Space: O(2N)

Efficient Approach: The above approach can also be optimized by using Dynamic Programming because it has Overlapping Subproblems property and Optimal Substructure property. Like other Dynamic Programming(DP) problems, recomputation of the same subproblems can be avoided by constructing a temporary array that stores the results of subproblems. Follow the steps below to solve the problem:

• Initialize a matrix, say dp[][] where dp[i][j] stores the maximum sum possible if there are j valid elements till position i and initializing dp[][] array with -1.
• Iterate over the range [0, N – 1] using the variable i and update dp[i][0] as 0.
• If the value of arr[0] is at least 0, then update dp[0][1] as arr[0]. Otherwise, update it as -1.
• Iterate over the range [1, N – 1] using the variable i:
• Iterate over the range [1, i + 1] using the variable j:
• If current element is excluded i.e., if dp[i – 1][j] is not equal to -1, then update dp[i][j] as max of dp[i][j] and dp[i – 1][j].
• If current element is included i.e., if dp[i – 1][j – 1] and dp[i – 1][j – 1] + arr[i] are greater than equal to 0, then update the value of dp[i][j] as the maximum of dp[i][j] and dp[i – 1][j – 1] + arr[i].
• Initialize a variable say, ans as 0 to store the longest subsequence with non-negative prefix sum at each position.
• Iterate in the range [0, N] using the variable j and if dp[N – 1][j] is greater than equal to 0, then update the value of ans as j.
• After completing the above steps, print the value of ans as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// Function to find the length of the``// longest subsequence with non negative``// prefix sum at each position``void` `longestSubsequence(``int``* arr, ``int` `N)``{``    ``// Stores the maximum sum possible``    ``// if we include j elements till``    ``// the position i``    ``int` `dp[N][N + 1];` `    ``// Initialize dp array with -1``    ``memset``(dp, -1, ``sizeof` `dp);` `    ``// Maximum subsequence sum by``    ``// including no elements till``    ``// position 'i'``    ``for` `(``int` `i = 0; i < N; ++i) {``        ``dp[i][0] = 0;``    ``}` `    ``// Maximum subsequence sum by``    ``// including first element at``    ``// first position``    ``dp[0][1] = (arr[0] >= 0 ? arr[0] : -1);` `    ``// Iterate over all the remaining``    ``// positions``    ``for` `(``int` `i = 1; i < N; ++i) {` `        ``for` `(``int` `j = 1;``             ``j <= (i + 1); ++j) {` `            ``// If the current element``            ``// is excluded``            ``if` `(dp[i - 1][j] != -1) {``                ``dp[i][j] = max(``                    ``dp[i][j], dp[i - 1][j]);``            ``}` `            ``// If current element is``            ``// included and if total``            ``// sum is positive or not``            ``if` `(dp[i - 1][j - 1] >= 0``                ``&& dp[i - 1][j - 1]``                           ``+ arr[i]``                       ``>= 0) {` `                ``dp[i][j] = max(``                    ``dp[i][j],``                    ``dp[i - 1][j - 1]``                        ``+ arr[i]);``            ``}``        ``}``    ``}` `    ``int` `ans = 0;` `    ``// Select the maximum j by which``    ``// a non negative prefix sum``    ``// subsequence can be obtained``    ``for` `(``int` `j = 0; j <= N; ++j) {``        ``if` `(dp[N - 1][j] >= 0) {``            ``ans = j;``        ``}``    ``}` `    ``// Print the answer``    ``cout << ans << endl;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 4, -4, 1, -3, 1, -3 };``    ``int` `N = ``sizeof` `arr / ``sizeof` `arr[0];``    ``longestSubsequence(arr, N);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.lang.*;``import` `java.util.*;` `class` `GFG{` `// Function to find the length of the``// longest subsequence with non negative``// prefix sum at each position``static` `void` `longestSubsequence(``int``[] arr, ``int` `N)``{``    ` `    ``// Stores the maximum sum possible``    ``// if we include j elements till``    ``// the position i``    ``int` `dp[][] = ``new` `int``[N][N + ``1``];` `    ``// Initialize dp array with -1``    ``for``(``int` `i = ``0``; i < N; ++i)``    ``{``        ``for``(``int` `j = ``0``; j < N + ``1``; ++j)``        ``{``            ``dp[i][j] = -``1``;``        ``}``    ``}``    ` `    ``// Maximum subsequence sum by``    ``// including no elements till``    ``// position 'i'``    ``for``(``int` `i = ``0``; i < N; ++i)``    ``{``        ``dp[i][``0``] = ``0``;``    ``}` `    ``// Maximum subsequence sum by``    ``// including first element at``    ``// first position``    ``dp[``0``][``1``] = (arr[``0``] >= ``0` `? arr[``0``] : -``1``);` `    ``// Iterate over all the remaining``    ``// positions``    ``for``(``int` `i = ``1``; i < N; ++i)``    ``{``        ``for``(``int` `j = ``1``; j <= (i + ``1``); ++j)``        ``{``            ` `            ``// If the current element``            ``// is excluded``            ``if` `(dp[i - ``1``][j] != -``1``)``            ``{``                ``dp[i][j] = Math.max(``                    ``dp[i][j], dp[i - ``1``][j]);``            ``}` `            ``// If current element is``            ``// included and if total``            ``// sum is positive or not``            ``if` `(dp[i - ``1``][j - ``1``] >= ``0` `&&``                ``dp[i - ``1``][j - ``1``] + arr[i] >= ``0``)``            ``{``                ``dp[i][j] = Math.max(dp[i][j],``                                    ``dp[i - ``1``][j - ``1``] +``                                   ``arr[i]);``            ``}``        ``}``    ``}` `    ``int` `ans = ``0``;` `    ``// Select the maximum j by which``    ``// a non negative prefix sum``    ``// subsequence can be obtained``    ``for``(``int` `j = ``0``; j <= N; ++j)``    ``{``        ``if` `(dp[N - ``1``][j] >= ``0``)``        ``{``            ``ans = j;``        ``}``    ``}` `    ``// Print the answer``    ``System.out.println(ans);``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``int` `arr[] = { ``4``, -``4``, ``1``, -``3``, ``1``, -``3` `};``    ``int` `N = arr.length;``    ` `    ``longestSubsequence(arr, N);``}``}` `// This code is contributed by avijitmondal1998`

## Python3

 `# Python3 Program for the above approach` `# Function to find the length of the``# longest subsequence with non negative``# prefix sum at each position``def` `longestSubsequence(arr, N):` `    ``# Stores the maximum sum possible``    ``# if we include j elements till``    ``# the position i` `    ``# Initialize dp array with -1``    ``dp ``=` `[[``-``1` `for` `i ``in` `range``(N ``+` `1``)] ``for` `i ``in` `range``(N)]` `    ``# Maximum subsequence sum by``    ``# including no elements till``    ``# position 'i'``    ``for` `i ``in` `range``(N):``        ``dp[i][``0``] ``=` `0` `    ``# Maximum subsequence sum by``    ``# including first element at``    ``# first position``    ``dp[``0``][``1``] ``=` `arr[``0``] ``if` `arr[``0``] >``=` `0` `else` `-``1` `    ``# Iterate over all the remaining``    ``# positions``    ``for` `i ``in` `range``(``1``, N):` `        ``for` `j ``in` `range``(``1``, i ``+` `2``):` `            ``# If the current element``            ``# is excluded``            ``if` `(dp[i ``-` `1``][j] !``=` `-``1``):``                ``dp[i][j] ``=` `max``(dp[i][j], dp[i ``-` `1``][j])` `            ``# If current element is``            ``# included and if total``            ``# sum is positive or not``            ``if` `(dp[i ``-` `1``][j ``-` `1``] >``=` `0` `and` `dp[i ``-` `1``][j ``-` `1``] ``+` `arr[i] >``=` `0``):` `                ``dp[i][j] ``=` `max``(dp[i][j], dp[i ``-` `1``][j ``-` `1``] ``+` `arr[i])` `    ``ans ``=` `0` `    ``# Select the maximum j by which``    ``# a non negative prefix sum``    ``# subsequence can be obtained``    ``for` `j ``in` `range``(N ``+` `1``):``        ``if` `(dp[N ``-` `1``][j] >``=` `0``):``            ``ans ``=` `j` `    ``# Print the answer``    ``print``(ans)` `# Driver Code`  `arr ``=` `[``4``, ``-``4``, ``1``, ``-``3``, ``1``, ``-``3``]``N ``=` `len``(arr)``longestSubsequence(arr, N)` `# This code is contributed by _saurabhy_jaiswal`

## C#

 `// C# program for the above approach``using` `System;` `class` `GFG{` `// Function to find the length of the``// longest subsequence with non negative``// prefix sum at each position``static` `void` `longestSubsequence(``int``[] arr, ``int` `N)``{``    ` `    ``// Stores the maximum sum possible``    ``// if we include j elements till``    ``// the position i``    ``int``[,] dp = ``new` `int``[N, N + 1];` `    ``// Initialize dp array with -1``    ``for``(``int` `i = 0; i < N; ++i)``    ``{``        ``for``(``int` `j = 0; j < N + 1; ++j)``        ``{``            ``dp[i, j] = -1;``        ``}``    ``}` `    ``// Maximum subsequence sum by``    ``// including no elements till``    ``// position 'i'``    ``for``(``int` `i = 0; i < N; ++i)``    ``{``        ``dp[i, 0] = 0;``    ``}` `    ``// Maximum subsequence sum by``    ``// including first element at``    ``// first position``    ``dp[0, 1] = (arr[0] >= 0 ? arr[0] : -1);` `    ``// Iterate over all the remaining``    ``// positions``    ``for``(``int` `i = 1; i < N; ++i)``    ``{``        ``for``(``int` `j = 1; j <= (i + 1); ++j)``        ``{``            ` `            ``// If the current element``            ``// is excluded``            ``if` `(dp[i - 1, j] != -1)``            ``{``                ``dp[i, j] = Math.Max(dp[i, j],``                                    ``dp[i - 1, j]);``            ``}` `            ``// If current element is``            ``// included and if total``            ``// sum is positive or not``            ``if` `(dp[i - 1, j - 1] >= 0 &&``                ``dp[i - 1, j - 1] + arr[i] >= 0)``            ``{``                ``dp[i, j] = Math.Max(dp[i, j],``                                    ``dp[i - 1, j - 1] +``                                    ``arr[i]);``            ``}``        ``}``    ``}` `    ``int` `ans = 0;` `    ``// Select the maximum j by which``    ``// a non negative prefix sum``    ``// subsequence can be obtained``    ``for``(``int` `j = 0; j <= N; ++j)``    ``{``        ``if` `(dp[N - 1, j] >= 0)``        ``{``            ``ans = j;``        ``}``    ``}` `    ``// Print the answer``    ``Console.Write(ans);``}` `// Driver code``public` `static` `void` `Main()``{``    ``int``[] arr = { 4, -4, 1, -3, 1, -3 };``    ``int` `N = arr.Length;` `    ``longestSubsequence(arr, N);``}``}` `// This code is contributed by ukasp`

## Javascript

 ``

Output:

`5`

Time Complexity: O(N2)
Auxiliary Space: O(N2)

My Personal Notes arrow_drop_up