Given an array of pairs A[][] of size N, the task is to find the longest subsequences where the first element is increasing and the second element is decreasing.
Examples:
Input: A[]={{1, 2}, {2, 2}, {3, 1}}, N = 3
Output: 2
Explanation: The longest subsequence satisfying the conditions is of length 2 and consists of {1, 2} and {3, 1};
Input: A[] = {{1, 3}, {2, 5}, {3, 2}, {5, 2}, {4, 1}}, N = 5
Output: 3
Naive Approach: The simplest approach is to use Recursion. For every pair in the array, there are two possible choices, i.e. either to include the current pair in the subsequence or not. Therefore, iterate over the array recursively and find the required longest subsequence.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int longestSubSequence(pair< int , int > A[], int N,
int ind = 0,
int lastf = INT_MIN,
int lasts = INT_MAX)
{
if (ind == N)
return 0;
int ans = longestSubSequence(A, N, ind + 1,
lastf, lasts);
if (A[ind].first > lastf
&& A[ind].second < lasts)
ans = max(ans, longestSubSequence(A, N, ind + 1,
A[ind].first,
A[ind].second)
+ 1);
return ans;
}
int main()
{
pair< int , int > A[] = { { 1, 2 },
{ 2, 2 },
{ 3, 1 } };
int N = sizeof (A) / sizeof (A[0]);
cout << longestSubSequence(A, N) << "\n" ;
return 0;
}
|
Java
import java.io.*;
class GFG{
public static Integer longestSubSequence( int [][] A, int N, int ind,
int lastf, int lasts)
{
ind = (ind > 0 ? ind : 0 );
lastf = (lastf > 0 ? lastf: Integer.MIN_VALUE);
lasts = (lasts > 0 ? lasts: Integer.MAX_VALUE);
if (ind == N)
return 0 ;
int ans = longestSubSequence(A, N, ind + 1 ,
lastf, lasts);
if (A[ind][ 0 ] > lastf && A[ind][ 1 ] < lasts)
ans = Math.max(ans, longestSubSequence(A, N, ind + 1 ,
A[ind][ 0 ], A[ind][ 1 ]) + 1 );
return ans;
}
public static int longestSubSequence( int [][] A, int N)
{
return longestSubSequence(A, N, 0 , 0 , 0 );
}
public static void main(String args[])
{
int [][] A = { { 1 , 2 }, { 2 , 2 }, { 3 , 1 } };
int N = A.length;
System.out.println(longestSubSequence(A, N));
}
}
|
Python3
import sys
def longestSubSequence(A, N,
ind = 0 ,
lastf = - sys.maxsize - 1 ,
lasts = sys.maxsize):
if (ind = = N):
return 0
ans = longestSubSequence(A, N, ind + 1 ,
lastf, lasts)
if (A[ind][ 0 ] > lastf
and A[ind][ 1 ] < lasts):
ans = max (ans, longestSubSequence(A, N, ind + 1 ,
A[ind][ 0 ],
A[ind][ 1 ])
+ 1 )
return ans
if __name__ = = "__main__" :
A = [[ 1 , 2 ],
[ 2 , 2 ],
[ 3 , 1 ]]
N = len (A)
print (longestSubSequence(A, N))
|
C#
using System;
class GFG{
public static int longestSubSequence( int [,] A, int N, int ind,
int lastf, int lasts)
{
ind = (ind > 0 ? ind : 0);
lastf = (lastf > 0 ? lastf: Int32.MinValue);
lasts = (lasts > 0 ? lasts: Int32.MaxValue);
if (ind == N)
return 0;
int ans = longestSubSequence(A, N, ind + 1,
lastf, lasts);
if (A[ind, 0] > lastf && A[ind, 1] < lasts)
ans = Math.Max(ans, longestSubSequence(A, N, ind + 1,
A[ind, 0], A[ind, 1]) + 1);
return ans;
}
public static int longestSubSequence( int [,] A, int N)
{
return longestSubSequence(A, N, 0, 0, 0);
}
public static void Main()
{
int [,] A = { { 1, 2 }, { 2, 2 }, { 3, 1 } };
int N = A.GetLength(0);
Console.Write(longestSubSequence(A, N));
}
}
|
Javascript
<script>
function longestSubSequence(A, N)
{
let dp = new Array(N);
for (let i = 0; i < N; i++) {
dp[i] = 1;
for (let j = 0; j < i; j++) {
if (A[j][0] < A[i][0]
&& A[j][1] > A[i][1]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
document.write(dp[N - 1] + "<br>" );
}
let A = [ [ 1, 2 ],
[ 2, 2 ],
[ 3, 1 ] ];
let N = A.length;
longestSubSequence(A, N);
</script>
|
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: This problem has Overlapping Subproblems property and Optimal Substructure property. Therefore, this problem can be solved using Dynamic Programming. Like other typical Dynamic Programming (DP) problems, recomputation of same subproblems can be avoided by constructing a temporary array that stores the results of the subproblems.
Follow the steps below to solve this problem:
- Initialize a dp[] array, where dp[i] stores the length of the longest subsequence that can be formed using elements up to index i.
- Iterate over the range [0, N-1] using variable i:
- Base case: Update dp[i] as 1.
- Iterate over the range [0, i – 1] using a variable j:
- If A[j].first is less than A[i].first and A[j].second is greater than A[i].second, then update dp[i] as maximum of dp[i] and dp[j] + 1.
- Finally, print dp[N-1].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void longestSubSequence(pair< int , int > A[], int N)
{
int dp[N];
for ( int i = 0; i < N; i++) {
dp[i] = 1;
for ( int j = 0; j < i; j++) {
if (A[j].first < A[i].first
&& A[j].second > A[i].second) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
cout << dp[N - 1] << endl;
}
int main()
{
pair< int , int > A[] = { { 1, 2 },
{ 2, 2 },
{ 3, 1 } };
int N = sizeof (A) / sizeof (A[0]);
longestSubSequence(A, N);
return 0;
}
|
Java
import java.io.*;
class GFG{
public static void longestSubSequence( int [][] A, int N)
{
int [] dp = new int [N];
for ( int i = 0 ; i < N; i++)
{
dp[i] = 1 ;
for ( int j = 0 ; j < i; j++)
{
if (A[j][ 0 ] < A[i][ 0 ] && A[j][ 1 ] > A[i][ 1 ])
{
dp[i] = Math.max(dp[i], dp[j] + 1 );
}
}
}
System.out.println(dp[N - 1 ]);
}
public static void main(String args[])
{
int [][] A = { { 1 , 2 },
{ 2 , 2 },
{ 3 , 1 } };
int N = A.length;
longestSubSequence(A, N);
}
}
|
Python3
def longestSubSequence(A, N):
dp = [ 0 ] * N
for i in range (N):
dp[i] = 1
for j in range (i):
if (A[j][ 0 ] < A[i][ 0 ] and A[j][ 1 ] > A[i][ 1 ]):
dp[i] = max (dp[i], dp[j] + 1 )
print (dp[N - 1 ])
if __name__ = = '__main__' :
A = [ [ 1 , 2 ],
[ 2 , 2 ],
[ 3 , 1 ] ]
N = len (A)
longestSubSequence(A, N)
|
C#
using System;
class GFG {
static void longestSubSequence( int [,] A, int N)
{
int [] dp = new int [N];
for ( int i = 0; i < N; i++)
{
dp[i] = 1;
for ( int j = 0; j < i; j++)
{
if (A[j,0] < A[i,0] && A[j,1] > A[i,1])
{
dp[i] = Math.Max(dp[i], dp[j] + 1);
}
}
}
Console.Write(dp[N - 1]);
}
static void Main()
{
int [,] A = { { 1, 2 },
{ 2, 2 },
{ 3, 1 } };
int N = A.GetLength(0);
longestSubSequence(A, N);
}
}
|
Javascript
<script>
function longestSubSequence(A, N) {
let dp = new Array(N);
for (let i = 0; i < N; i++) {
dp[i] = 1;
for (let j = 0; j < i; j++) {
if (A[j][0] < A[i][0]
&& A[j][1] > A[i][1]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
document.write(dp[N - 1] + "<br>" );
}
let A = [[1, 2],
[2, 2],
[3, 1]];
let N = A.length;
longestSubSequence(A, N);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N)