Longest non decreasing sequence - n log n? - algorithm

I am trying to understand the n log n solution. It seems that you dont have to store the entire temp lists at any given point, just the last element would do.
How does that work?
I didnt want to post on the existing posts, so created a new one.
Spent a lot of time understanding it. . :(

you don't have to store the entire temp lists at any given point, just the last element would do.
First, recall the O(n2) solution: you set up an array L that has at each element i the length of the longest non-decreasing subsequence of A ending at element i. Here is an example:
A: 2 5 7 3 8 2 9 6 9
L: 1 2 3 2 4 2 5 3 6
Now imagine setting up an array M, which at each index k stores the element of A that ends the longest non-decreasing subsequence of length k. Here is how M would look at each step (dash - shows places that are not filled in)
M (step 0) - - - - - - - - -
M (step 1) 2 - - - - - - - -
M (step 2) 2 5 - - - - - - -
M (step 3) 2 5 7 - - - - - -
M (step 4) 2 3 7 - - - - - -
M (step 5) 2 3 7 8 - - - - -
M (step 6) 2 2 7 8 - - - - -
M (step 7) 2 2 7 8 9 - - - -
M (step 8) 2 2 6 8 9 - - - -
M (step 9) 2 2 6 8 9 9 - - -
Work through the example manually to understand the mechanics of filling out the array M.
Now comes the key observation: at each step, M is ordered in non-decreasing order. Intuitively, this is clear, because otherwise the larger number could be attached to a longer sequence, and be moved up the array M.
This lets you construct your algorithm:
Store the last position maxPos of M that has been filled in
When you arrive at A[i], run a binary search in M[0..maxPos] for a place where A[i] should be placed
If you end up in the middle of the array, replace the old value with min(A[i], oldValue)
If the element is larger than or equal to all elements added to M so far, add A[i] to the end, and increment maxPos
It is easy to see that the above algorithm is O(n*log(n)), because each of its n steps uses a binary search, which is log(n).

Related

What is N in this given scenario

I am trying to implement this code and this website has kindly provided their algorithm but I am trying to Find out what is "N" I understood what "I" and "M" is but not "N", is "N" the Total input(in the below example 5 because there are 5 letters)?
Algorithm:
Combinations are generated in lexicographical order. The algorithm uses indexes of the elements of the set. Here is how it works on example: Suppose we have a set of 5 elements with indexes 1 2 3 4 5 (starting from 1), and we need to generate all combinations of size m
= 3.
First, we initialize the first combination of size m - with indexes in ascending order
1 2 3
Then we check the last element (i = 3). If its value is less than n - m + i, it is incremented by 1.
1 2 4
Again we check the last element, and since it is still less than n - m
i, it is incremented by 1.
1 2 5
Now it has the maximum allowed value: n - m + i = 5 - 3 + 3 = 5, so we move on to the previous element (i = 2).
If its value less than n - m + i, it is incremented by 1, and all following elements are set to value of their previous neighbor plus 1
1 (2+1)3 (3+1)4 = 1 3 4
Then we again start from the last element i = 3
1 3 5
Back to i = 2
1 4 5
Now it finally equals n - m + i = 5 - 3 + 2 = 4, so we can move to first element (i = 1) (1+1)2 (2+1)3 (3+1)4 = 2 3 4
And then,
2 3 5
2 4 5
3 4 5
and it is the last combination since all values are set to the maximum possible value of n - m + i.
Input:
A
B
C
D
E
Output:
A B C
A B D
A B E
A C D
A C E
A D E
B C D
B C E
B D E
C D E
Take a look at the very first paragraf of the link you provided.
It states that
This combinations calculator generates all possible combinations of m elements from the set of n elements.
So yes, n is the number of elements or letters that the algorithm needs to use.
N here is the size of the set of set from which you generate the combinations. In the given example, "Suppose we have a set of 5 elements with indexes 1 2 3 4 5 (starting from 1)", N is 5.
Combinations are usually symbolized with nCm, or n choose m. So n is the total set size(in this example 5) and m is the number chosen(3).

Finding number representation in different bases

I was recently solving a problem when I encountered this one: APAC Round E Q2
Basically the question asks to find the smallest base (>1) in which if the number (input) is written then the number would only consist of 1s. Like 3 if represented in base 2 would become 1 (consisting of only 1s).
Now, I tried to solve this the brute force way trying out all bases from 2 till the number to find such a base. But the constraints required a more efficient one.
Can anyone provide some help on how to approach this?
Here is one suggestion: A number x that can be represented as all 1s in a base b can be written as x = b^n + b^(n-1) + b^(n-2) + ... + b^1 + 1
If you subtract 1 from this number you end up with a number divisble by b:
b^n + b^(n-1) + b^(n-2) + ... + b^1 which has the representation 111...110. Dividing by b means shifting it right once so the resulting number is now b^(n-1) + b^(n-2) + ... + b^1 or 111...111 with one digit less than before. Now you can repeat the process until you reach 0.
For example 13 which is 111 in base 3:
13 - 1 = 12 --> 110
12 / 3 = 4 --> 11
4 - 1 = 3 --> 10
3 / 3 = 1 --> 1
1 - 1 = 0 --> 0
Done => 13 can be represented as all 1s in base 3
So in order to check if a given number can be written with all 1s in a base b you can check if that number is divisble by b after subtracting 1. If not you can immediately start with the next base.
This is also pretty brute-forcey but it doesn't do any base conversions, only one subtraction, one divisions and one mod operation per iteration.
We can solve this in O( (log2 n)^2 ) complexity by recognizing that the highest power attainable in the sequence would correspond with the smallest base, 2, and using the formula for geometric sum:
1 + r + r^2 + r^3 ... + r^(n-1) = (1 - r^n) / (1 - r)
Renaming the variables, we get:
n = (1 - base^power) / (1 - base)
Now we only need to check power's from (floor(log2 n) + 1) down to 2, and for each given power, use a binary search for the base. For example:
n = 13:
p = floor(log2 13) + 1 = 4:
Binary search for base:
(1 - 13^4) / (1 - 13) = 2380
...
No match for power = 4.
Try power = 3:
(1 - 13^3) / (1 - 13) = 183
(1 - 6^3) / (1 - 6) = 43
(1 - 3^3) / (1 - 3) = 13 # match
For n around 10^18 we may need up to (floor(log2 (10^18)) + 1)^2 = 3600 iterations.

Number of steps taken to split a number

I cannot get my head around this:
Say I got a number 9. I want to know the minimum steps needed to split it so that no number is greater than 3.
I always thought that the most efficient way is to halve it every loop.
So, 9 -> 4,5 -> 2,2,5 -> 2,2,2,3 so 3 steps in total. However, I just realised a smarter way: 9 -> 3,6 -> 3,3,3 which is 2 steps only...
After some research, the number of steps is in fact (n-1)/target, where target=3 in my example.
Can someone please explain this behaviour to me?
If we want to cut a stick of length L into pieces of size no greater than S, we need ceiling(L/S) pieces. Each time we make a new cut, we increase the number of pieces by 1. It doesn't matter what order we make the cuts in, only where. For example, if we want to break a stick of length 10 into pieces of size 2 or less:
-------------------
0 1 2 3 4 5 6 7 8 9 10
we should cut it in the following places:
---|---|---|---|---
0 1 2 3 4 5 6 7 8 9 10
and any order of cuts is fine, as long as these are the cuts that are made. On the other hand, if we start by breaking it in half:
---------|---------
0 1 2 3 4 5 6 7 8 9 10
we have made a cut that isn't part of the optimal solution, and we have wasted our time.
I really like #user2357112's explanation of why cutting in half is not the right first step, but I also like algebra, and you can prove that ceil(n / target) - 1 is optimal using induction.
Let's prove first that you can always do it in ceil(n / target) - 1 steps.
If n <= target, obviously no step are required, so the formula works. Suppose n > target. Split n into target and n - target (1 step). By induction, n - target can be split in ceil((n - target)/target) - 1 steps. Therefore the total number of steps is
1 + ceil((n - target) / target) - 1
= 1 + ceil(n / target) - target/target - 1
= ceil(n / target) - 1.
Now let's prove that you can't do it in fewer than ceil(n / target) - 1 steps. This is obvious if n <= target. Suppose n > target and the first step is n -> a + b. By induction, a requires at least ceil(a / target) - 1 steps and b requires at least ceil(b / target) - 1 steps. The minimum number of steps required is therefore at least
1 + ceil(a / target) - 1 + ceil(b / target) - 1
>= ceil((a + b) / target) - 1 using ceil(x) + ceil(y) >= ceil(x + y)
= ceil(n / target) - 1 using a + b = n
Every n can be thought of as a priority queue of \lfloor n/target \rfloor target elements placed first on the queue and one element whose value is n%target. Every time you remove an element from the queue, you place it back on the queue. Remove all but the last element: you have clearly removed \lfloor (n-1)/target \rfloor elements. If the last element is less than or equal to the target, we are done. If it is greater than the target, we have a contradiction. So, after \lfloor (n-1)/target \rfloor steps we have a queue consisting only of elements less than or equal to target.

Arithmetic operation on sequence on integers

I have N integers numbers: 1,2,3...N
The task is to use +,-,*,/ to make expression 0.
For example -1*2+3+4-5=0
How can I do it?
May be some code on C/C++ ?
If N % 4 == 0, for every four consecutive integers a, b, c, d, take a - b - c + d
If N % 4 == 1, use 1 * 2 to start, then proceed as before. (i.e., 1*2 - 3 - 4 + 5 + 6 - 8 - 8 + 9 ...)
If N % 4 == 2, start with 1 - 2 + 3 * 4 - 5 - 6, then proceed as in the N % 4 == 0 example.
If N % 4 == 3, start with 1 + 2 - 3, then proceed as in the N%4 == 0 example.
All of these find a way to get zero out of the first few integers, leaving a multiple of four integers to work on, then take advantage of the fact that the pattern a - b - c + d = 0 for any four consecutive integers.
This is essentially SAT, or do you know that the numbers are a sequence (e.g. 2 1 8 is forbidden). What about negative numbers?
If the sequence is not too large, i would recommend to simply bootforce it. A greedy solution would be to reduce the problem by finding subsets which can be evaluated to zero.

Lower bound on clique number

What is the smallest clique number (that is maximum clique size) possible for a graph with n vertices and m edges? I was thinking of using Turan's theorem, but that just tells us an upper bound on the number of edges given the clique number. I've been stuck on this for days, and could use some help.
I don't believe this question has a simple answer (as is often the case with Ramsey-esque problems), but here is an approach to get you started (I'm assuming this is homework and so I won't try to work it all the way out).
Assume the graph is connected (without this assumption, the problem only gets harder). Let k be the smallest clique number possible. The extreme cases are:
If n = m-1 (equivalently, the graph is a tree), then k=2.
If m = (n choose 2) (equivalently, the graph is complete), then k=n.
From this one might reasonably infer that as m increases relative to n, k should also increase. Go with this idea and see where it takes you.
I worked out the numbers for small n,m and the results are not in OEIS, though possibly I made a computational error (please let me know if you find one). Here are the numbers:
n\m | 0 1 2 3 4 5 6 7 8 9 10
---------------------------
1 | 1 - - - - - - - - - -
2 | - 2 - - - - - - - - -
3 | - - 2 3 - - - - - - -
4 | - - - 2 2 3 4 - - - -
5 | - - - - 2 2 2 3 3 4 5
6 | - - - - - 2 2 2 2 2 3
Again, I'm assuming connected (at least n-1 edges) and no loops (at most (n choose 2) edges).

Resources