Counting the strictly increasing sequences - algorithm

I aligned the N candles from left to right. The ith candle from the left has the height Hi and the color Ci, an integer ranged from 1 to a given K, the number of colors.
Problem: , how many strictly increasing ( in height ) colorful subsequences are there? A subsequence is considered as colorful if every of the K colors appears at least one times in the subsequence.
For Ex: N=4 k= 3
H C
1 1
3 2
2 2
4 3
only two valid subsequences are (1, 2, 4) and (1, 3, 4)
I think it is a problem of Fenwick Tree please provide me a approach how to proceeded with such type of problems

For a moment, let's forget about the colors. So the problem is simpler: count the number of increasing subsequences. This problem has a standard solution:
1. Map each value to [0...n - 1] range.
2. Let's assume the f[value] is the number of increasing subsequences that have value as their last element.
3. Initially, f is filled with 0.
4. After that, you iterate over all array elements from left to right and perform the following operation: f[value] += 1 + get_sum(0, value - 1)(it means that you add this element to all possible subsequences so that they remain strictly increasing), where value is the current element of the array and get_sum(a, b) returns the sum of f[a] + f[a + 1] + ... + f[b].
5. The answer is f[0] + f[1] + ... + f[n - 1].
Using binary index tree(aka Fenwick tree), it is possible to do get_sum operation in O(log n) and get O(n log n) total time complexity.
Now let's come back to the original problem. To take into account the colors, we can compute f[value, mask] instead of f[value](that is, the number of increasing subsequences that have value as their last element and mask(it is a bitmask that shows which colors are present) colors). Then an update for each element looks like this:
for mask in [0...2^K - 1]:
f[value, mask or 2^(color[i] - 1)] += 1 + get_sum(0, value - 1, mask)
The answer is f[0, 2^K - 1] + f[1, 2^K - 1] + ... + f[n - 1, 2^K - 1].
You can maintain 2^K binary index trees to achieve O(n * log n * 2^K) time complexity using the same idea as in a simpler problem.

Related

Algorithm-Find sum in matrix

We are given 2D matrix array (let's say length i and wide j) and integer k
We have to find size of smallest rectangle, that contains this or greater sum
F.e k=7
4 1
1 1
1 1
4 4
Anwser is 2, because 4+4=8 >= 7, if there wasn't last line, anwser would be 4, 4+1+1+1 = 7 >= 7
My idea is to count prefix sums Pref[k,l]=Tab[k,l]+Pref[k-1,l]+Pref[k,l-1]
And then compare every single rectangle
Is this possible to make it faster? My idea is T(n)=O(n^2) (Where n is number of elements in matrix)
I would like to do this in time n or n * log n
I would be really glad if someone would give me any tip how to do this :)
First, create an auxillary matrix: sums, where:
sums[i,j] = A[0,0] + A[0,1] + .... + A[0,j] + A[1,0] + ... + A[1,j] + ... + A[i,j]
I think this is what you meant when you said "prefix matrix".
This can be calculated in linear time with dynamic programming:
sums[0,j] = A[0,0] + ... + A[0,j]
sums[i,0] = A[0,0] + ... + A[i,0]
sums[i,j] = sums[i-1,j] + sums[i,j-1] - sums[i-1,j-1] + A[i,j]
^
elements counted twice
Now, assuming all elements are non negative, this is non decreasing, matrix, where each column and each row are sorted.
So, iterating the matrix again, for each pair of indices i,j, find the value closest yet smaller than sum[i,j]-k.
This can be done in O(sqrt(n)).
Do it for each such (i,j) pair, and you get O(n*sqrt(n)) solution.

Explanation for recursive implementation of Josephus problem

EDIT: n is the number of persons. k is the kth person being eliminated. So for k=2, every 2nd person is getting eliminated.
int josephus(int n, int k)
{
if (n == 1)
return 1;
else
return (josephus(n - 1, k) + k-1) % n + 1;
}
The code is as simple as it could be. But somehow I am unable to understand this problem (which is a little embarassing to be honest).
The way I am trying to understand it is,
josephus(n,k) gives the final solution for a population of size n and step size k.
josephus(n,k) can be calculated if we know the solution for josephus(n-1,k). That is in my opinion "optimal substructure property" of dynamic programming.
I get that we need to do a MOD N so that in case number goes past n, it will again start counting from 1. (i.e. ensure that addition behaves like we are counting in a circle). But why did we add this "k-1"?
The main question is if we know the correct solution of josephus(n-1,k), how are we calculating the solution to josephus(n,k). We have effectively added one more person to the population and somehow adding this k-1 value is giving me the correct solution (let's ignore mod for a moment).
Can anyone explain this to me that how is the optimal substructure property holding at each step in the problem?
The key insight that made this solution make sense for me is the following: the result of josephus(n, k) is best not thought of as the number that is the Josephus survivor, but rather as the index of the number that is the Josephus survivor. For example, calling josephus(5, 2) will tell you the index of the person out of a ring of five that ends up surviving.
With that intuition in mind, let's think about how the Josephus problem works by looking at a concrete example. Suppose we want to know josephus(n, 2). You can imagine we have n people lined up like this:
1 2 3 4 5 ... n
The first thing that happens is that person 1 kills person 2, as shown here:
1 X 3 4 5 ... n
Now, we're left with a subproblem of the following form: there are n-1 people remaining, every other person is going to be killed, and the first person who will be doing the stabbing is person 3. In other words, we're left with a ring of people shaped like this:
3 4 5 ... n 1
with k = 2. Now, imagine that we make a recursive call to josephus(n - 1, 2), since we have n - 1 people. This will give back the index of who survives in a line of n - 1 people. Given that we have the index of the person who will survive, and we also know who the starting person is, we can determine which person will be left. Here's how we'll do it.
The starting person in this line is the person who comes right after the person who was last executed. This will be person 3. The 1-indexed position of the survivor in the ring of four people is given by josephus(n - 1, 2). We can therefore walk forward josephus(n - 1, 2) - 1 positions, wrapping around the ring if necessary, to get to our final position. In other words, the survivor is given by position
(3 + josephus(n - 1, 2) - 1) % n
There's a problem with this above formula, though. If we are indeed using one-indexing, what happens if the final survivor is at position n? In that case, we'd accidentally get back position 0 as our answer, but we really want position n. As a fix to this, we'll use a trick for using mod to wrap around with one-indexing: we'll take the inside quantity (the one-indexed position) and subtract one to get the zero-indexed position. We'll mod that quantity by n to get the zero-indexed position wrapped around. Finally, we'll add back one to get the one-indexed position, wrapped around. That looks like this:
(3 + josephus(n - 1, 2) - 2) % n + 1
The -2 term here therefore comes from two independent -1's: the first -1 is because josephus(n - 1, 2) returns a one-indexed index, so to step forward by the right number of positions we have to take josephus(n - 1, 2) - 1 steps forward. The second -1 comes from the fact that we're using one-indexing rather than zero-indexing.
Let's generalize this to work for arbitrary k, not just k = 2. Suppose we want to know josephus(n, k). In that case, person 1 will stab person k, leaving us with an array like this:
1 2 3 ... k-1 X k+1 ... n
We now essentially need to solve a subproblem where person k+1 comes first:
k+1 k+2 ... n 1 2 ... k-1
So we compute josephus(n - 1, k) to get the one-indexed survivor of a ring of n - 1 people, then shift forward by that many steps:
(k+1 + josephus(n - 1, k) - 1)
We need to worry about the case where we wrap around, so we need to mod by n:
(k+1 + josephus(n - 1, k) - 1) % n
However, we're one-indexed, so we need to use the trick of subtracting 1 from the inside quantity and then adding 1 at the end:
(k+1 + josephus(n - 1, k) - 2) % n + 1
which simplifies to
(k-1 + josephus(n - 1, k)) % n + 1
which is equivalent to
(josephus(n - 1, k) + k-1) % n + 1
as in the solution code.
To summarize: the k-1 term comes from starting at position k+1, adding in josephus(n - 1, k) - 1 to shift forward the appropriate amount, then subtracting one and adding one back in at the end to do the correct wraparound.
Hope this helps!
We need to adjust the position by k-1 simply because the starting position has been shift by k after the kth is removed (and the first k-1 are rotated to the end). That is, initial position pos becomes pos-k. If k = 3, (n-1,k) returned pos = 2, the original position should be pos + k = 5.
We replace k with k-1 in the formula because we have to mod(n): k = (k-1) % n + 1

Probabilty based on quicksort partition

I have come across this question:
Let 0<α<.5 be some constant (independent of the input array length n). Recall the Partition subroutine employed by the QuickSort algorithm, as explained in lecture. What is the probability that, with a randomly chosen pivot element, the Partition subroutine produces a split in which the size of the smaller of the two subarrays is ≥α times the size of the original array?
Its answer is 1-2*α.
Can anyone explain me how has this answer come?Please Help.
The choice of the pivot element is random, with uniform distribution.
There are N elements in the array, and we will assume that N is large (or we won't get the answer we want).
If 0≤α≤1, the probability that the number of elements smaller than the pivot is less than αN is α. The probability that the number of elements greater than the pivot is less than αN is the same. If α≤ 1/2, then these two possibilities are exclusive.
To say that the smaller subarray is of length ≥αN, is to say that neither of these conditions holds, therefore the probability is 1-2α.
The other answers didn't quite click with me so here's another take:
If at least one of the 2 subarrays must be you can deduce that the pivot must also be in position . This is obvious by contradiction. If the pivot is then there is a subarray smaller than . By the same reasoning the pivot must also be . Any larger value for the pivot will yield a smaller subarray than on the "right hand side".
This means that , as shown by the diagram below:
What we want to calculate then is the probability of that event (call it A) i.e .
The way we calculate the probability of an event is to sum of the probability of the constituent outcomes i.e. that the pivot lands at .
That sum is expressed as:
Which easily simplifies to:
With some cancellation we get:
Just one more approach for solving the problem (for those who have uneasy time understanding it, like I have).
First.
Since we are talking about "the smaller of the two subarrays", then its length is less than 1/2 * n (n - the number of elements in original array).
Second.
If 0 < a < 0.5 it means the a * n is less than 1/2 * n either.
And thus we are talking from now about two randomly chosen integers bounded by 0 at lowest and 1/2 * n at highest.
Third.
Lets imagine the dice with numbers from 1 to 6 on it's sides. Lets choose a number from 1 to 6, for example 4. Now roll the dice. Each number has a probability 1/6 to be the outcome of this roll. Thus for event "outcome is less or equal to 4" we have probability equal to the sum of probabilities of each of this outcomes. And we have numbers 1, 2, 3 and 4. Altogether p(x <= 4) = 4 * 1/6 = 4/6 = 2/3. So the probability of event "output is bigger than 4" is p(x > 4) = 1 - p(x <= 4) = 1 - 2/3 = 1/3.
Fourth.
Lets go back to our problem. The "chosen number" is now a * n. And we are going to roll the dice with the numbers from 0 to (1/2 * n) on it to get k - the number of elements in a smallest of subarrays. The probability that outcome is bounded by (a * n) at highest is equals to sum of the probabilities of all outcomes from 0 to (a * n). And the probability for any particular outcome k is p(k) = 1 / (1/2 * n).
Therefore p(k <= a * n) = (a * n) * (1 / (1/2 * n)) = 2 * a.
From this we can easily conclude that p(k > a * n) = 1 - p(k <= a * n) = 1 - 2 * a.
Array length is n.
For smaller array length >= αn pivot should be greater than αn number of elements. At the same time pivot should be smaller than αn number of elements( else smaller array size will be less than required)
So out of n element we have to select one among (n-2α)n elements.
required probability is n(1-2α)/n.
Hence 1-2α
The probability would be, the number of desired elements/Total number of elements.
In this case, ((1-αn)-(αn))/n
Since α lies between,0 and 0.5,(1-α) must be bigger than α.Hence the number of elements contained between them would be,
(1-α-α)n=(1-2α)n
and so,the probability would be,
(1-2α)n/n=1-2α
Another approach:
List the "more balanced" options:
αn + 1 to (1 - α)n - 1
αn + 2 to (1 - α)n - 2
...
αn + k to (1 - α)n - k
So k in total. We know that the most balanced is n / 2 to n / 2, so:
αn + k = n / 2 => k = n(1/2 - α)
Similarly, list the "less balanced" options:
αn - 1 to (1 - α)n + 1
αn - 2 to (1 - α)n + 2
...
αn - m to (1 - α)n + m
So m in total. We know that the least balanced is 0 to n so:
αn - m = 0 => m = αn
Since all these options happen with equal probability we can use the frequency definition of probability so:
Pr{More balanced} = (total # of more balanced) / (total # of options) =>
Pr{More balanced} = k / (k + m) = n(1/2 - α) / (n(1/2 - α) + αn) = 1 - 2α

Maximum of sums of unsorted array and each of a number of sorted arrays

Given an unsorted array
A = a_1 ... a_n
And a set of sorted Arrays
B_i = b_i_1 ... b_i_n # for i from 1 to $large_number
I would like to find the maximums from the (not yet calculated) sum arrays
C_i = (a_1 + b_i_1) ... (a_n + b_i_n)
for each i.
Is there a trick to do better than just calculating all the C_i and finding their maximums in O($large_number * n)?
Can we do better when we know that the B arrays are just shifts from an endless sequence,
e.g.
S = 0 1 4 9 16 ...
B_i = S[i:i+n]
(The above sequence has the maybe advantageous property that (S_i - S_i-1 > S_i-1 - S_i-2))
There are $large_number * n data in your first problem, so there can't be any such trick.
You can prove this with an adversary argument. Suppose you have an algorithm that solves your problem without looking at all n * $large_number entries of b. I'm going to pick a fixed a, namely (-10, -20, -30, ..., -10n). The first $large_number * n - 1 the algorithm looks at an entry b_(i,j), I'll answer that it's 10j, for a sum of zero. The last time it looks at an entry, I'll answer that it's 10j+1, for a sum of 1.
If $large_number is Omega(n), your second problem requires you to look at n * $large_number entries of S, so it also can't have any such trick.
However, if you specify S, there may be something. And if $large_number <= n/2 (or whatever it is), then, all of the entries of S must be sorted, so you only have to look at the last B.
If we don't know anything I don't it's possible to do better than O($large_number * n)
However - If it's just shifts of an endless sequence we can do it in O($large_number + n):
We calculate B_0 ןמ O($large_number).
Than B_1 = (B_0 - S[0]) + S[n+1]
And in general: B_i = (B_i-1 - S[i-1]) + S[i-1+n].
So we can calculate all the other entries and the max in O(n).
This is for a general sequence - if we have some info about it, it might be possible to do better.
we know that the B arrays are just shifts from an endless sequence,
e.g.
S = 0 1 4 9 16 ...
B_i = S[i:i+n]
You can easily calculate S[i:i+n] as (sum of squares from 1 to i+n) - (sum of squares from 1 to i-1)
See https://math.stackexchange.com/questions/183316/how-to-get-to-the-formula-for-the-sum-of-squares-of-first-n-numbers
With the provided example, S1 = 0, S2 = 1, S3 = 4...
Let f(n) = SUM of Si for i=1 to n = (n-1)(n)(2n-1)/6
B_i = f(i+n) - f(i-1)
You then add SUM(A) to each sum.
Another approach is to calculate the difference between B_i and B_(i-1):
That would be: S[i:i+n] - S[i-1:i+n-1] = S(i+n) - S(i-1)
That way, you can just calculate the difference of the sums of each array with the previous one. In my understanding, since Ci = SUM(Bi)+SUM(A), SUM(A) becomes a constant that is irrelevant in finding the maximum.

Getting i'th prefix without computing others

I read this post which is quite close to the problem I'm having, but couldn't generalize it.
I'm trying to solve the Traveling Sales Person by searching all paths using multiple CPU's.
What I need, is a way to encode a path prefix to integer and distribute it to each CPU so it would know what paths it's supposed to scan.
For example, if the number of cities is 10 one possible 3-prefix (suppose prefix length is fixed and known) is 4-10-3 (there are 10*9*8 prefixes), so the CPU which would receive it, would search all paths that begin with 4-10-3.
Since the number of cities is quite large, I can't compute n! thus I can't use the post above.
The standard representation of a permutation as a number uses Lehmer codes represented in the factorial number system. The idea is that every permutation of n elements can be mapped to a sequence of n numbers, the first of which is in the range 0 to (n - 1), the second of which is in the range 0 to (n - 2), etc. This sequence of numbers can then be represented as a single integer in the factorial number system.
I believe that it should be possible to adapt this trick to work with prefixes of permutations rather than entire permutations. Suppose that you have n elements and want to choose a permutation of k of them. To do this, start off by computing the Lehmer code for the partial permutation. Instead of getting a sequence of n numbers, you'll get back a sequence of k numbers. For example, given the partial permutation c a d drawn from a b c d e f g, your Lehmer code would be found as follows:
c is the second (zero-indexed) element of a b c d e f g
a is the zeroth (zero-indexed) element of a b d e f g
d is the first (zero-indexed) element of b d e f g
So the Lehmer code would be (2, 0, 1).
Once you have this Lehmer code, you can try to encode it as a single integer. To do this, you can use a modified factorial number system encoding. Specifically, you can try doing the following. If you have n elements and want a permutation of k of them, then there will be a total of (n - k + 1) possible choices for the very last element. There are a total of (n - k + 2) possible choices for the second-to-last element, (n - k + 3) possible choices for the third-to-last element, etc. Consequently, you could take your Lehmer code and do the following:
Keep the final digit unchanged.
Multiply the second-to-last element by (n - k + 1).
Multiply the third-to-last element by (n - k + 1)(n - k + 2)
4 ...
Multiply the first element by (n - k + 1)(n - k + 2)...(n - 1)
Sum up these values.
This produces a unique integer code for the permutation.
For example, our Lehmer code was (2, 0, 1), n = 7, and k = 3. Therefore, we'd compute
1 + 0 × (7 - 3 + 1) + 2 × (7 - 3 + 2)(7 - 3 + 3)
= 1 + 2 × (5 × 6)
= 5 + 2 × 30
= 61
To invert this process, you can take the integer and run it backwards through this procedure to recover the partial Lehmer code. To do this, start off by taking the number and dividing by (n - k + 1)(n - k + 2)...(n - 1) to get back the very first digit of the Lehmer code. Then, mod the number by (n - k + 1)(n - k + 2)...(n - 1) to drop off the first digit. Then, divide the number by (n - k + 1)(n - k + 2)...(n - 2) to get back the second digit of the Lehmer code, then mod by (n - k + 1)(n - k + 2)...(n - 2) to drop off the second digit. Repeat this until all the digits of the Lehmer code have been reconstructed.
For example, given prefix 61, n = 7, and k = 3, we would start off by dividing 61 by 7 × 6 = 30. This gives 2, remainder 1. Thus the first digit of the Lehmer code is 2. Modding by 30, we get back the number 1. Next, we divide by 6. This gives 0, remainder 1. Thus the second digit is 0. Finally, we read off the remaining number, which gives the last digit of the Lehmer code, 1. We have recovered our Lehmer code (2, 0, 1), from which we can easily reconstruct the permutation.
Hope this helps!
The easiest way here is to map the prefix without treating it as part of a permutation. Don't map the prefix to [0,10*9*8-1], but rather to [0,10*10*10-1], so the prefix 0,4,5 will be mapped to the number 45, and the prefix 4,1,9 will be mapped to the number 419 (assuming there are 10 cities over-all, of course).

Resources