Reputation: 575
I am trying to solve the following question :
A sequence in which the value of elements first decrease and then increase is called V- Sequence. In a valid V-Sequence there should be at least one element in the decreasing and at least one element in the increasing arm.
For example, "5 3 1 9 17 23" is a valid V-Sequence having two elements in the decreasing arm namely 5 and 3, and 3 elements in the increasing arm namely 9, 17 and 23 . But none of the sequence "6 4 2" or "8 10 15" are V-Sequence since "6 4 2" has no element in the increasing part while "8 10 15" has no element in the decreasing part.
A sub-sequence of a sequence is obtained by deleting zero or more elements from the sequence. For example definition "7", "2 10", "8 2 7 6", "8 2 7 10 6" etc are valid sub-sequences of "8 2 7 10 6"
Given a sequence of N numbers find its longest sub-sequence which is a V-Sequence.
I currently have an O( n^2 ) solution wherein I first initialize an array ( m[] ) such that each m[i] contains the longest increasing sequences STARTING at 'i' within the array.
Similarly, I initialize another array ( d[] ), such that each d[i] contains the longest decreasing sequence ENDING at that point.
Both of these operations take O( n^2 )
I now go through these arrays and choose the maximum value of m[i] + d[i] -1 , such that required conditions are satisfied.
What I want to know is - Is there an O( n lg n ) solution ?? Because my solution does not run within required time limits. Thank you :)
CODE :
#include<cstdio>
#include<algorithm>
using namespace std;
int m[ 200000 ];
int d[200000 ];
int n;
int arr[200000 ];
void LIS()
{
m[ n-1 ] = 1;
int maxvPos = -1;
int maxv = -1;
for( int i=n-2; i>=0; i-- )
{
maxv = -1;
for( int j=i+1; j<n; j++ )
{
if( ( m[j]+1 > maxv ) && ( arr[i] < arr[j]) )
{
maxv = m[j]+1;
maxvPos = j;
}
}
if( maxv>0 )
{
m[i] = maxv;
}
else
m[i ] = 1;
}
}
void LDS()
{
d[0] = 1;
int maxv = -1;
int maxvPos = -1;
for( int i=1; i<n; i++ )
{
maxv = -1;
for( int j=i-1; j>=0; j-- )
{
if( ( d[j]+1 > maxv) && arr[j]>arr[i] )
{
maxv = d[j]+1;
maxvPos = j;
}
}
if( maxv>0 )
d[i] = maxv;
else
d[i]=1;
}
}
int solve()
{
LIS();
LDS();
int maxv = 0;
int curr = 0;
for( int i=0; i<n; i++ )
{
curr = d[i] + m[i] -1 ;
if( ( d[i]>0) && (m[i]>0 ))
{
if( curr != 1 )
maxv = max( curr, maxv );
}
}
return maxv;
}
/* static void printArr( int[] a )
{
for( int i : a )
System.out.print( i + " ");
System.out.println();
} */
int main()
{
scanf( "%d", &n );
for( int i=0; i<n; i++ )
{
scanf("%d", &arr[i] );
}
printf("%d\n", solve() );
return 0;
}
Upvotes: 5
Views: 2891
Reputation: 139
Construct array inc[i] where inc[i] stores Longest Increasing subsequence ending with A[i]. Construct array dec[i] where dec[i] stores Longest Decreasing subsequence ending with A[i].
then find the maximum value of (inc[i] + dec[i] - 1)
Upvotes: 0
Reputation: 51
This one is a O(n) solution.
Checked it on basic examples.
Let me know if it has any problem or if it does not work for any particular case.
CODE :
#include<stdio.h>
int max(int a,int b)
{
return (a >= b ? a : b);
}
int main()
{
int i,j,n;
scanf("%d",&n);
int A[200022];
int dec[200022]={0};
int V[200022]={0};
int state[200022]={0};
for(i=0;i<n;i++)
{
scanf("%d",&A[i]);
}
if(A[0] > A[1])
state[0]=1;
for(i=1;i<n;i++)
{
j=i-1;
if(A[i] < A[j])
{
dec[i]=max(dec[i],dec[j]+1);
V[i]=max(V[i],V[j]);
state[i]=1;
}
else if(A[i] == A[j])
{
dec[i]=dec[j];
V[i]=V[j];
state[i]=state[j];
}
else
{
if(state[j]==1)
{
dec[i]=dec[i];
V[i]=max(V[i],dec[j]+1);
V[i]=max(V[i],V[j]+1);
state[i]=1;
}
else
{
dec[i]=dec[i];
V[i]=max(V[i],V[j]);
}
}
// printf("%d %d\n",dec[i],V[i]);
}
if(V[n-1] == 0)
printf("0\n");
else
printf("%d\n",V[n-1]+1);
}
Upvotes: 0
Reputation: 6891
Edit: Oh, this answer is wrong. I missed the part about being able to delete elements to make longer conforming sequences. Still, for entertainment, here's a solution for the simple case where you don't get to delete elements:
I can think of an O(n) solution:
Walk the list once. Maintain some variables:
Initialise both start pointers to the first element, the longest to zero, and the scan state to descending.
Upvotes: 0
Reputation: 594
There are O(NlgK)
algorithm for Longest Increasing Subsequence problem, where K
is the LIS length. You can check Wikipedia for a description of the algorithm. LightOJ also has a nice tutorial (this might require login).
Upvotes: 5