Circular Longest Increasing Subsequence - algorithm

How can I find the length of Longest Increasing Sub-sequence if the numbers are arranged in circular fashion. For example:
LIS of 3, 2, 1 is 3 [1, 2, 3].
P.S I know how to solve Linear LIS in O(nlogn).
Problem Source: https://www.codechef.com/problems/D2/
Update: The LIS has to be calculated by going through the circle only once.
Example 2: LIS of 1, 4, 3 is 2 and that could be either of 1, 3 or 1, 4 or 3, 4.
Thanks

The example in question is wrong. circular rotation of [1,2,3] would be [2,3,1] or [3,1,2].
In which case, we can solve it similar way as longest increasing subsequence. As:
Sort the list in ascending order.
Find min element in the original list.
Start iteration from min_index in original list and compare it with sorted list, and create intermediate array L[i][j] with same logic as longest common subsequence. i will vary from min_index to (i+n-1)%n
Finally return L[max_index][n]

Related

Why is an ancestral array needed when recovering longest increasing subsequence?

I looked at the following website describing the longest increasing subsequnce algorithm: https://www.fyears.org/2016/12/LIS.html
In the section "how to reconstruct the subsequence?", it says that
"We should pay attention that the dp in the end is NOT the LIS."
Somehow I don't see how dp is not LIS?
We know that dp is sorted and that it contains as many entries modified by the algorithm as the length of the LIS. An element at index i cannot be equal to an element at i-1, since for every index dp[i] contains the smallest possible ending value in all increasing subsequences with length i + 1. So, if there is a subsequence of length i + 1, this implies that there is also a subsequence of length i, which consequently must end at a smaller value, right?
LIS is a subsequence (fixed order of elements), but DP array isn't saving elements order. Check on array [2, 3, 1]. DP will be [1, 3] after all iterations, but [1, 3] isn't the subsequence of the initial array.

Is there any algorithm to address the longest common subsequence problem with different weights for each character?

I'm looking for an algorithm that addresses the LCS problem for two strings with the following conditions:
Each string consists of English characters and each character has a weight. For example:
sequence 1 (S1): "ABBCD" with weights [1, 2, 4, 1, 3]
sequence 2 (S2): "TBDC" with weights [7, 5, 1, 2]
Suppose that MW(s, S) is defined as the maximum weight of the sub-sequence s in string S with respect to the associated weights. The heaviest common sub-sequence (HCS) is defined as:
HCS = argmin(MW(s, S1), MW(s, S2))
The algorithm output should be the indexes of HCS in both strings and the weight. In this case, the indexes will be:
I_S1 = [2, 4] --> MW("BD", "ABBCD") = 7
I_S2 = [1, 2] --> MW("BD", "TBDC") = 6
Therefore HCS = "BD", and weight = min(MW(s, S1), MW(s, S2)) = 6.
The table that you need to build will have this.
for each position in sequence 1
for each position in sequence 2
for each extreme pair of (weight1, weight2)
(last_position1, last_position2)
Where an extreme pair is one where it is not possible to find a subsequence to that point whose weights in sequence 1 and weights in sequence 2 are both >= and at least one is >.
There may be multiple extreme pairs, where one sequence is higher than the other.
The rule is that at the (i, -1) or (-1, j) positions, the only extreme pair is the empty set with weight 0. At any other we merge the extreme pairs for (i-1, j) and (i, j-1). And then if seq1[i] = seq2[j], then add the options where you went to (i-1, j-1) and then included the i and j in the respective subsequences. (So add weight1[i] and weight2[j] to the weights then do a merge.)
For that merge you can sort by weight1 ascending, all of the extreme values for both previous points, then throw away all of the ones whose weight2 is less than or equal to the best weight2 that was already posted earlier in the sequence.
When you reach the end you can find the extreme pair with the highest min, and that is your answer. You can then walk the data structure back to find the subsequences in question.

Find 2 subarrays from an array of n elements that have equal or close to sum of their elements

Let's say you have an array = [2, 3, 3, 6, 7], it is not sorted, but you can sort it if you would like. Find 2 subarrays using all the elements in the array so that the resulting subarrays will be [2, 3, 6] and [7, 3] since 2 + 3 + 6 = 11 and 7 + 3 = 10.
The sums of the resulting subarrays don't have to be equal but they should be as close as they can be.
My first approach was sorting this elements in desc order and taking elements from each end of the array.
Any help will be appreciate it, thanks.
Suppose the sum of all the numbers is N. To determine whether there is a solution where the two subsets have equal sum is equivalent to the problem of determining whether there is a subset that adds to N / 2.
The best known algorithms for this problem are exponential.
I've found out that this is a well-known problem known as the partition problem. For more information: https://en.wikipedia.org/wiki/Partition_problem

add elements of array thats sum equals the largest element

what is a way to add elements of array thats sum would equal the largest element in the array?
example for this array [4, 6, 23, 10, 1, 3] I have sorted the array first resulting in [1, 3, 4, 6, 10, 23] then I pop the last digit or the last element max = 23. I'm left with [1, 3, 4, 6, 10] and need a way to find a way to find the elements that add up to 23 which are 3 + 4 + 6 + 10 = 23. The elements don't have to be subsequent they can be at random points of the array but they must add up to max.
I can find the permutations of the sorted array from 2 elements to n-1 elements and sum them and compare them to max but that seems inefficient. plz help
This is exactly the subset sum problem, which is NP-Complete, but if your numbers are relatively small integers, there is an efficient pseudo-polynomial solution using Dynamic Programming:
D(i,0) = TRUE
D(0,x) = FALSE x>0
D(i,x) = D(i-1,x) OR D(i-1,x-arr[i])
If there is a solution, you need to step back in the matrix created by the DP solution, and "record" each choice you have made along the way, to get the elements used for the summation. This thread deals with how to find the actual elements in a very similar problem (known as knapsack problem), which is solved similarly: How to find which elements are in the bag, using Knapsack Algorithm [and not only the bag's value]?

Summing a given series of numbers in order to reset the summation as many times as possible algorithm

I'm looking for an efficient algorithm (not necessarily a code) for solving the following question:
Given n positive and negative numbers that sum up to zero, we would like to find a starting index that will cause the cumulated sum to zero up as many times as possible.
It doesn't have to be in a specific manner, but the importance here is the efficincy- we want the algorithm/idea to be able to this in less then a qudratic "time complexity"
An example:
Given the numbers: 2, -1, 3, 1, -3, -2:
If we strat summing up with 2 (first index), the sum will be zero only once (at the end of the summation), but strting with -1 will yield zero twice during the summation.
The given numbers may have more than one "best index", but we would like to find at least one of these indexes.
I've tried doing it with binary search, but didn't make much progress- so any hints/help will be appreciated.
You can compute prefix sums. In terms of prefix sums, zeros are positions that have the same value of a prefix sum as the start position. So the problem is reduced to finding the most frequent element in the array of prefix sums. It can be solved efficiently using sorting or hash tables.
Here is an example:
Input: {2, -1, 3, 1, -3, 2}
Prefix sums: {0, 2, 1, 4, 5, 2, 0}
The most frequent element is 2. The first occurrence of 2 is in the first position. Thus, starting from the second element yields optimal answer.

Resources