Given N "A"s and N "B"s. We need to arrange them such that if A is on left of B then our solution increase by +1 and also we need to maintain that at every point the number of A's must be greater than or equal to number of B's.
Now we need to count such permutations of these 2*N alphabets such that solution is equal to K every time.
Example : Say N=4 and K=2 then here answer is 6.
6 possible ways are :
ABAAABBB
AABBAABB
AABAABBB
AAABABBB
AAABBABB
AAABBBAB
My approach : I am having O(N*K) approach to solve this problem by doing brute type solution.
Make a function say F(last,Acount,K) and then check if we can place A or B their satisfying the conditions.But problem is N and K can be large .
So how to solve this problem
Short answer: Narayana numbers is what you need.
I've spent whole saturday researching your problem. Thanks for an interesting question :) Here I would like to tell you my steps to solve it if you are interested.
You said that you can brute force the problem for a small inputs. For an algorithmic problems this ofthen might give you such an insight for better solution (e.g. if you find out some relations and guess the generating function). So I did brute force too (with dynamic programming aproach) and looked at given numbers. First time I wrote it to my output file wrong way (for every K for all N one after another in one column) so I didn't find some beatiful relations. That's why I didn't find answer that time and spent some more to get better reccurent function.
Then I tried to deduce it to nonreccurent function but failed (I think because it wasn't the best one possible). However doing this I found relations like Pascal triangle has (kind of symmetry) and then wrote numbers sequence to the output file in a triangle way.
It looked like very nice sequence so I just googled some of its numbers and found links to Narayana numbers.
Then I tried to deduce nonreccurent formula with no success again (now I could check its correctness because the sequence formula is already knonwn) :) So this time I don't know exactly how Narayana numbers' formula is given although the formula seems simple and small but you can search more if you are interested. I wish I go deep more but I'm afraid of spending the whole holidays for it :)
Here my brute force solution #1 and better reccurent solution #2. And here the outputs I've got in a triangle way (word wrap makes it ugly so be careful).
Also, thanks DavidEisenstat for pointing the right way in comment to your question. I checked that link but didn't go further googling to find a solution. Although that would be the shortest path to the answer your question.
UPDATE I didn't provide implementation of fast calculation of combinations. There're different ways to do this which you can simply find in the internet including its implementations. The complexity of calculations would be O(N) so you will pass the execution time bounds you have. Or if you need to answer the query (with different N and K) multiple times, you can precalculate factorial for every number from 1 to N modulo (1e6 + 9) and then use them to calculate combinations with O(1).
Now that there's a spoiler, let me expand on my comment.
Given a string with n ('s and n )'s, append a ). Exactly one of its n + 1 rotations ending in ) begins with a length-2n parenthesized expression. This is one way to prove the Catalan formula
C(n) = (2n choose n) / (n + 1).
For this problem, we want to count only the parenthesized expressions that have k occurrences of (). The number of ordered partitions of n elements into k nonempty parts is (n - 1) choose (k - 1), by choosing k - 1 positions out of n - 1 to insert part boundaries. By partitioning n + 1 into k nonempty parts also, we can count the number of length-(2n + 1) strings that begin with (, end with ), and have n ('s and n + 1 )'s and k ()'s as
((n - 1) choose (k - 1)) (n choose (k - 1)).
Of these strings, exactly k rotations result in strings of the same form, hence the division by k to get the number that are parenthesized properly. (There is no rotational symmetry because if k > 1 then k fails to divide n or n + 1.) The final answer is
((n - 1) choose (k - 1)) (n choose (k - 1)) / k.
To compute the binomial coefficients quickly, cache the factorials and their inverses modulo the modulus up to the maximum value of n.
Related
You are given an array of positive integers of size N. You can choose any positive number x such that x<=max(Array) and subtract it from all elements of the array greater than and equal to x.
This operation has a cost A[i]-x for A[i]>=x. The total cost for a particular step is the
sum(A[i]-x). A step is only valid if the sum(A[i]-x) is less than or equal to a given number K.
For all the valid steps find the minimum number of steps to make all elements of the array zero.
0<=i<10^5
0<=x<=10^5
0<k<10^5
Can anybody help me with any approach? DP will not work due to high constraints.
Just some general exploratory thoughts.
First, there should be a constraint on N. If N is 3, this is much easier than if it is 100. The naive brute force approach is going to be O(k^N)
Next, you are right that DP will not work with these constraints.
For a greedy approach, I would want to minimize the number of distinct non-zero values, and not maximize how much I took. Our worst case approach is take out the largest each time, for N steps. If you can get 2 pairs of entries to both match, then that shortened our approach.
The obvious thing to try if you can is an A* search. However that requires a LOWER bound (not upper). The best naive lower bound that I can see is ceil(log_2(count_distinct_values)). Unless you're incredibly lucky and the problem can be solved that quickly, this is unlikely to narrow your search enough to be helpful.
I'm curious what trick makes this problem actually doable.
I do have an idea. But it is going to take some thought to make it work. Naively we want to take each choice for x and explore the paths that way. And this is a problem because there are 10^5 choices for x. After 2 choices we have a problem, and after 3 we are definitely not going to be able to do it.
BUT instead consider the possible orders of the array elements (with ties both possible and encouraged) and the resulting inequalities on the range of choices that could have been made. And now instead of having to store a 10^5 choices of x we only need store the distinct orderings we get, and what inequalities there are on the range of choices that get us there. As long as N < 10, the number of weak orderings is something that we can deal with if we're clever.
It would take a bunch of work to flesh out this idea though.
I may be totally wrong, and if so, please tell me and I'm going to delete my thoughts: maybe there is an opportunity if we translate the problem into another form?
You are given an array A of positive integers of size N.
Calculate the histogram H of this array.
The highest populated slot of this histogram has index m ( == max(A)).
Find the shortest sequence of selections of x for:
Select an index x <= m which satisfies sum(H[i]*(i-x)) <= K for i = x+1 .. m (search for suitable x starts from m down)
Add H[x .. m] to H[0 .. m-x]
Set the new m as the highest populated index in H[0 .. x-1] (we ignore everything from H[x] up)
Repeat until m == 0
If there is only a "good" but not optimal solution sought for, I could imagine that some kind of spectral analysis of H could hint towards favorable x selections so that maxima in the histogram pile upon other maxima in the reduction step.
I'm having a hard time figuring out formulas that are used to solve a given problem more efficiently.
For example, a problem I have encountered was the following:
n children are placed in a circle. Every kth child is given chocolate until a child that has already been given chocolate is
selected again. Determine the nr number of children that don't
receive chocolate, given n and k.
Ex: n = 12, k = 9; nr will be 8.
This problem can be solved in 2 ways:
Creating a boolean array and traversing it until a child that hasn't been given chocolate is selected (not really efficient);
Using the formula: n - n / GCD(n, k);
How would I go about figuring out the 2nd way of solving it (the formula)?
Also, where can I practice this specific type of problem, where there is an obvious, slow way of solving it or an efficient one requiring you to figure out a formula?
Every problem is different, there is no rule to find a solution. You need to analyse the situation and reason about it. Mathematical training helps a lot.
For this concrete example you can proceed like this: number the children from 0 to n-1. If you start at 0, the children getting chocolate are exactly the ones with a number divisible by GCD(n, k). How many are there: n / GDC(n, k) therefore, how many don't get chocolate: n -n / GDC(n, k).
I have two questions, which I have trying but unable to figure them out.
1) 𝑇(𝑛) = 𝑇(𝑛 − 1) + 𝑛^4
2) 𝑇(𝑛) = 2𝑇 (𝑛/2) + 𝑛 lg 𝑛
For first one, I am assuming substitution (am I correct?), and got kb + T(n-k). Pretty sure that's wrong so need help with it.
For the second one, I have no idea at all...
Any help would be great! Thanks!
1) So you got
...? I don't know how you obtained this but it's certainly incorrect.
This is basically the summation of the 4th power of all integers up to n. The standard formula for this is:
2) We can find a pattern if we keep expanding this:
The limit log n - 1 is because we keep dividing the parameter to T by 2, so the substitution as above can continue for log n lines until, say T(1) or wherever the stopping condition is. Continuing using the logarithm rules (google them if you don't know):
Both summations have log n terms. Since the 1st summation does not depend on i at all, we simply multiply by log n. The 2nd summation is given by a standard formula for summation of integers from 1 (or 0, doesn't matter in this case):
Sometimes I see a problem and I'm not sure whether my first instinct should be to brute force all possible solutions + memoize or try to solve the problem intelligently. For example, this problem:
Given a positive integer n and you can do operations as follow:
If n is even, replace n with n/2. If n is odd, you can replace n with
either n + 1 or n - 1. What is the minimum number of replacements
needed for n to become 1?
How does one know not to code something that tries every single option for any given n (for example: 1 + [func(n+1), func(n-1), func(n/2)].min instead of looking for a more intelligent solution? How do you know to have that instinct?
The problem I'm having can be reduced to:
Given an array of N positive numbers, find the non-contiguous sequence of exactly K elements with the minimal sum.
Ok-ish: report the sum only. Bonus: the picked elements can be identified (at least one set of indices, if many can realize the same sum).
(in layman terms: pick any K non-neighbouring elements from N values so that their sum is minimal)
Of course, 2*K <= N+1 (otherwise no solution is possible), the problem is insensitive to positive/negative (just shift the array values with the MIN=min(A...) then add back K*MIN to the answer).
What I got so far (the naive approach):
select K+2 indexes of the values closest to the minimum. I'm not sure about this, for K=2 this seems to be the required to cover all the particular cases, but I don't know if it is required/sufficient for K>2**
brute force the minimal sum from the values of indices resulted at prev step respecting the non-contiguity criterion - if I'm right and K+2 is enough, I can live brute-forcing a (K+1)*(K+2) solution space but, as I said. I'm not sure K+2 is enough for K>2 (if in fact 2*K points are necessary, then brute-forcing goes out of window - the binomial coefficient C(2*K, K) grows prohibitively fast)
Any clever idea of how this can be done with minimal time/space complexity?
** for K=2, a non-trivial example where 4 values closest to the absolute minimum are necessary to select the objective sum [4,1,0,1,4,3,4] - one cannot use the 0 value for building the minimal sum, as it breaks the non-contiguity criterion.
PS - if you feel like showing code snippets, C/C++ and/or Java will be appreciated, but any language with decent syntax or pseudo-code will do (I reckon "decent syntax" excludes Perl, doesn't it?)
Let's assume input numbers are stored in array a[N]
Generic approach is DP: f(n, k) = min(f(n-1, k), f(n-2, k-1)+a[n])
It takes O(N*K) time and has 2 options:
for lazy backtracking recursive solution O(N*K) space
for O(K) space for forward cycle
In special case of big K there is another possibility:
use recursive back-tracking
instead of helper array of N*K size use map(n, map(k, pair(answer, list(answer indexes))))
save answer and list of indexes for this answer
instantly return MAX_INT if k>N/2
This way you'll have lower time than O(NK) for K~=N/2, something like O(Nlog(N)). It will increase up to O(N*log(N)Klog(K)) for small K, so decision between general approach or special case algorithm is important.
There should be a dynamic programming approach to this.
Work along the array from left to right. At each point i, for each value of j from 1..k, find the value of the right answer for picking j non-contiguous elements from 1..i. You can work out the answers at i by looking at the answers at i-1, i-2, and the value of array[i]. The answer you want is the answer at n for an array of length n. After you have done this you should be able to work out what the elements are by back-tracking along the array to work out whether the best decision at each point involves selecting the array element at that point, and therefore whether it used array[i-1][k] or array[i-2][k-1].