Monday, August 26, 2013

Longest Increasing and Decreasing Subsequence problem

You have a sequence of numbers from which you must create the longest subsequence satisfying the following condition: it can be 'cut' into two parts that share exactly one common element (the last element of the first part is the first element of the second part), and the first part is sorted in strictly ascending order while the second part is sorted in strictly descending order. For example, the sequence { 1, 4, 6, 5, 2, 1 } can be 'cut' into { 1, 4, 6 } and { 6, 5, 2, 1 }. The two parts share the 6, and the first sequence is sorted in ascending order while the second sequence is sorted in descending order.
You are given a int[] numbers, a sequence of numbers. Return the minimal number of elements you must throw out from the given sequence such that the remaining subsequence satisfies the condition described above.

0)
{1, 4, 6, 5, 2, 1}
Returns: 0
This sequence already satisfies the condition, so the answer is 0.
1)
{1, 2, 1, 2, 3, 2, 1, 2, 1}
Returns: 4
The longest subsequence is { 1, 2, 3, 2, 1 }, so you need to throw out at least 4 elements.
2)
{2, 2, 2, 2, 2}
Returns: 4
3)
{4,5,65,34,786,45678,987,543,2,6,98,580,4326,754,54,2,1,3,5,6,8,765,43,3,54}
Returns: 14

http://community.topcoder.com/stat?c=problem_statement&pm=5922


public class IncreasingDecreasingSubseq {


public static void findMinimumCuts(int arr[])
{

int size = arr.length;
int lis[] = new int[size];
int lds[] = new int[size];
// Longest Increasing sequence
for(int i = 0; i < size; ++i)
{
for(int j = 0; j < i; ++j)
{
if(arr[j] < arr[i])
{
lis[i] = Math.max(lis[j] + 1, lis[i]);
}
}
}

// Longest decreasing sequence
for(int i = size - 1; i >= 0; --i)
{
for(int j = size - 1; j > i; --j)
{
if(arr[j] < arr[i])
{
lds[i] = Math.max(lds[j] + 1, lds[i]);
}
}
}

int best = 0;
for(int i = 0; i < size; ++i)
{
best = Math.max(best, lds[i] + lis[i]);
}
System.out.println("Best"+best);
System.out.println("Number to be removed : " + (size - best - 1));

}

public static void main(String[] args) {

int a[] = {1, 2, 1, 2, 3, 2, 1, 2, 1};
int b[] = {4,5,65,34,786,45678,987,543,2,6,98,580,4326,754,54,2,1,3,5,6,8,765,43,3,54};
findMinimumCuts(a);
findMinimumCuts(b);
}

}

No comments: