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
Related
I am unable to determine the time complexity of a backtracking solution for the climbing stairs problem which states
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
Input: 2
Output: 2
Explanation: There are two ways to climb to the
top.
1 step + 1 step
2 steps
My algorithm:
input = [1, 2]
output = set()
n = 4
def helper(temp):
if sum(temp) == n:
output.add(tuple(temp))
elif sum(temp) > n:
return
else:
for i in input:
helper(temp + [i])
helper([])
print(output)
Output for n = 4:
{(1, 2, 1), (2, 1, 1), (1, 1, 2), (2, 2), (1, 1, 1, 1)}
This function's runtime is the unusual Θ(n · φn), where φ is the golden ratio, (1 + √5) / 2.
To see why this is, let's talk about how to analyze the code that you've written. Imagine the recursion tree for this code. (That's the tree with one node for each recursive call made). Notice that each recursive call branches - there's one call to a subproblem of size n - 1 and one subcall to a problem of size n - 2. In any tree where each internal node is branching, the number of total nodes is at most twice the number of leaves. And in your case, there's one leaf for each solution found, plus some additional leaves for when the recursion overshoots the value of n. (For now, we'll ignore that second group, but we'll talk about why that is later on.) This means that the total number of recursive calls is (with the previous caveat addressed later) at most twice the number of paths down stairs.
So how many solutions are there to this problem? Turns out, the number of solutions for a staircase of height n is exactly equal to the nth Fibonacci number, and the nth Fibonacci number happens to be Θ(φn). So that means that there are a total of Θ(φn) total recursive calls made.
So how much work do those recursive calls take? We can conservatively upper-bound each recursive call's work at O(n), since in the worst case summing up the list adds up 1 + 1 + 1 + ... + 1 n times. But we can also lower-bound the work done at the leaves, where the work is greatest, at Ω(n) because in the best case we add up 2 + 2 + ... + 2 a total of n / 2 times.
Overall, we have Θ(φn) calls, of which the bottom ones do Θ(n) work each, for a total of Θ(n · φn) work.
There's one last detail to address - what about the recursive calls that "overshoot" and add up to something bigger than n? Turns out, there's also O(φn) of these as well. One way to see this is that the number of ways of overshooting to hit n + 1 is at most the number of solutions to listing all paths of size n + 1, and there's O(φn) of these. So adding these back in doesn't change anything.
Hope this helps!
I've read the editorial but it's very short and claims something I don't understand why it's true. Why is it equivalent to finding longest subsequence of 1*2*1*2*?. Can someone explain the solution step by step and justify the claims at every step? http://codeforces.com/contest/934/problem/C
Here is the 'solution' from the editorial, but as I said it's very short and I don't understand it. Hope someone can guide me to the solution step by step justifying the claims along the way, not like in the solution here. Thanks.
Since 1 ≤ ai ≤ 2, it's equivalent to find a longest subsequence like
1 * 2 * 1 * 2 * . By an easy dynamic programming we can find it in
O(n) or O(n2) time. You can see O(n2) solution in the model
solution below. Here we introduce an O(n) approach: Since the
subsequence can be split into 4 parts (11...22...11...22...) , we
can set dp[i][j](i = 1...n, j = 0..3) be the longest subsequence of
a[1...i] with first j parts.
I also think that the cited explanation is not super clear. Here is another take.
You can collapse an original array
1 1 2 2 2 1 1 2 2 1
into a weighted array
2 3 2 2 1
^ ^ ^ ^ ^
1 2 1 2 1
where numbers at the top represent lengths of contiguous strips of repeated values in the original array.
We can convince ourselves that
The optimal flip does not "break up" any contiguous sequences.
The optimal flip starts and ends with different values (i.e. starts with 1 and ends with 2, or starts with 2 and ends with 1).
Hence, the weighted array contains enough information to solve the problem. We want to flip a contiguous slice of the weighted array s.t. the sum of weights associated with some contiguous monotonic sequence is maximized.
Specifically, we want to perform the flip in such a way that some contiguous monotonic sequence 112, 122, 211 or 221 has maximum weight.
One way to do this with dynamic programming is by creating 4 auxiliary arrays.
A[i] : maximal weight of any 1 to the right of i.
B[i] : maximal weight of any 1 to the left of i.
C[i] : maximal weight of any 2 to the right of i.
D[i] : maximal weight of any 2 to the left of i.
Let's assume that if any of A,B,C,D is accessed out of bounds, the returned value is 0.
We initialize x = 0 and do one pass through the array Arr = [1, 2, 1, 2, 1] with weights W = [2, 3, 2, 2, 1]. At each index i, we have 2 cases:
Arr[i:i+2] == 1 2. In this case we set
x = max(x, W[i] + W[i+1] + C[i+1], W[i] + W[i+1] + B[i-1]).
Arr[i:i+2] == 2 1. In this case we set
x = max(x, W[i] + W[i+1] + A[i+1], W[i] + W[i+1] + D[i-1]).
The resulting x is our answer. This is an O(N) solution.
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.
Hot or cold.
I think you have to do some sort of binary search but I'm not sure how.
Your goal is the guess a secret integer between 1 and N. You
repeatedly guess integers between 1 and N. After each guess you learn
if it equals the secret integer (and the game stops); otherwise
(starting with the second guess), you learn if the guess is hotter
(closer to) or colder (farther from) the secret number than your
previous guess. Design an algorithm that finds the secret number in lg
N + O(1) guesses.
Hint: Design an algorithm that solves the problem in lg N + O(1)
guesses assuming you are permitted to guess integers in the range -N
to 2N.
I've been racking my brain and I can't seem to come up with a a lg N + O(1).
I found this: http://www.ocf.berkeley.edu/~wwu/cgi-bin/yabb/YaBB.cgi?board=riddles_cs;action=display;num=1316188034 but could not understand the diagram and it did not describe other possible cases.
Suppose you know that your secret integer is in [a,b], and that your last guess is c.
You want to divide your interval by two, and to know whether your secret integer lies in between [a,m] or [m,b], with m=(a+b)/2.
The trick is to guess d, such that (c+d)/2 = (a+b)/2.
Without loss of generality, we can suppose that d is bigger than c. Then, if d is hotter than c, your secret integer will be bigger than (c+d)/2 = (a+b)/2 = m, and so your secret integer will lie in [m,b]. If d is cooler than c, your secret integer will belong to [a,m].
You need to be able to guess between -N and 2N because you can't guarantee that c and d as defined above will always be [a,b]. Your two first guess can be 1 and N.
So, your are dividing your interval be two at each guess, so the complexity is log(N) + O(1).
A short example to illustrate this (results chosen randomly):
Guess Result Interval of the secret number
1 *** [1 , N ] // d = a + b - c
N cooler [1 , N/2 ] // N = 1 + N - 1
-N/2 cooler [N/4 , N/2 ] //-N/2 = 1 + N/2 - N
5N/4 hotter [3N/8, N/2 ] // 5N/4 = N/4 + N/2 + N/2
-3N/8 hotter [3N/8, 7N/16] //-3N/8 = 3N/8 + N/2 - 5N/4
. . . .
. . . .
. . . .
Edit, suggested by #tmyklebu:
We still need to prove that our guess will always fall in bewteen [-N,2N]
By recurrence, suppose that c (our previous guess) is in [a-(a+b), b+(a+b)] = [-b,a+2b]
Then d = a+b-c <= a+b-(-b) <= a+2b and d = a+b-c >= a+b-(a+2b) >= -b
Initial case: a=1, b=N, c=1, c is indeed in [-b,a+2*b]
QED
This was a task at IOI 2010, for which I sat on the Host Scientific Committee. (We asked for an optimal solution instead of simply lg N + O(1), and what follows is not quite optimal.)
Not swinging outside -N .. 2N and using lg N + 2 guesses is straightforward; all you need to do is show that the obvious translation of binary search works.
Once you have something that doesn't swing outside -N .. 2N and takes lg N + 2 guesses, do this:
Guess N/2, then N/2+1. This tells you which half of the array the answer is in. Then guess the end of that half-array. You're either in one of the two "middle" quarters or you're in one of the two "end" quarters. If you're in a middle quarter, do the thing before and you win in lg N + 4 guesses. The ends are slightly trickier.
Suppose I need to guess a number in 1 .. K without straying outside 1 .. N and my last guess was 1. If I guess K/2 and I'm colder, then I next guess 1; I spent two guesses to get a similar subproblem that's 1/4 the size. If K/2 is hotter, I know the answer is in K/4 .. K. Guess K/2-1 next. The two subcases are K/4 .. K/2-1 and K/2 .. K, both of which are nice. But it took me three guesses to (in the worst-case) halve the size of the problem; if I ever do this, I wind up doing lg N + 6 guesses.
The solution is close to binary search. At each step you have an interval that the number can be in. Start with the whole interval [1, N]. First guess both ends - that is the numbers 1 and N. One of them will be closer, thus you will know that now the number you are searching for is in [1, N/2] or in [N/2 + 1, N](considering N even for simplicity). Now you go to the next step having a twice smaller interval. Continue using the same approach. Keep in mind that you've already probed one of the ends, however it may not be your last guess.
I am not sure what you mean by lg N + O(1), but the approach I suggest will perform O(log(N)) operations and in the worst case it will do exactly log4(N) probes.
Here're my two cents for this problem, since I got obsessed with it for two days. I'm not going to say anything new to what others have already said, but I'm going to explain it in a way that might get some people to understand the solution easily(or at least that was the way I managed to understand it).
Drawing from the ~ 2 lg N solution, if I knew that solution existed in [a, b] I'd want to know if it's in the left half [a, (a + b) / 2] or the right half [(a + b) / 2, b], with the point (a + b) / 2 separating the two halves. So what do I do? I guess a then b; if I get colder with b I know I'm in the first(left) half, if I get hotter I know I'm in the second(right) one. So guessing a and b is the way to know the secret integer position with respect to the mid point (a + b) / 2. However a and b aren't the only points that I can guess at to know the secret position. (a - 1, b + 1), (a - 2, b + 2), ... etc are all valid pairs of points to guess at to know the secret position, as the mid point of all these pairs is (a + b) / 2, the mid point of the original interval [a, b]. In fact any two numbers c and d such that (c + d) / 2 = (a + b) / 2 can be used.
So considering [a, b] as the interval we know the secret integer exists within, take c to be the last number we guessed. We want to determine the position of the secret with respect to the mid point (a + b) / 2, so we a new number d to guess at to know the secret relative position to (a + b) / 2. How do we know such number d? By solving the equation (c + d) / 2 = (a + b) / 2, which yields d = a + b - c. Guessing at that d, we shrink the range [a, b] appropriately based on the answer(colder or hotter) and then repeat the process taking d as our last guess and trying a new guess at number e for example with the same conditions.
To establish the initial conditions, we should start with a = 1, b = N, and c = 1. We guess at c to establish a reference(since the first guess can't tell you anything useful as there were no prior guesses). We then proceed with new guesses and adjusting the enclosing interval as appropriate with each guess. The table in #R2B2's answer explains it all.
You have to be vigilant however when trying to code this solution. When I tried to code it in python, I first ran into the mistake of getting [a, b] stuck when it was small enough(like [a, a + 1]) where neither a nor b would move inwards. I had to phase the cases where the interval size was 2 outside the loop and handle them separately(like I did with intervals with size 1 also).
the task is quite brain cracking
but I'll try to keep it simple
to solve the problem in 2lnN let's make following guesses:
1 and N : to decide which half is hotter (1, N/2) or (N/2, N), for example (N/2, N) is the hotter half, then let's make next guesses
N/2 and N : again to decide which half is hotter (N/2, 3/4N) or (3/4N, N) and so on
... so we need 2 guesses for every half-division, therefore we should make 2 * lnN guesses.
here we see that each time we need to repeat one of previous intervals' borders one more time - in our example point 'N' is repeated.
to solve the problem in 1*lnN guesses instead of 2*lnN, we need to find way to spend only one guess for each intervals' half-division, good illustration of such method is depicted on image at http://www.ocf.berkeley.edu/~wwu/cgi-bin/yabb/YaBB.cgi?board=riddles_cs;action=display;num=1316188034
the idea is to avoid repeating one of border points of each interval again in subsequent steps, but be smart to spend one guess for each half-division step by mirroring points.
the smart idea is that when we want to decide which half of current interval is hotter, we don't need to try only its borders, but we can as well try any points located outside its borders, these guessing points must be at equal distances (in other words mirrored) relatively to the center of interesting interval, nothing bad even if these guessing points are negative (i.e. < 0) or if they are > N (this is not prohibited by the conditions of the task)
so to guess the secret we can freely make guesses using pounts in interval (-N, 2N)
public class HotOrCold {
static int num=5000;// number to search
private static int prev=0;
public static void main(String[] args) {
System.out.println(guess(1,Integer.MAX_VALUE));
}
public static int guess(int lo,int hi) {
while(hi>=lo) {
boolean one=false;
boolean two=false;
if(hi==lo) {
return lo;
}
if(isHot(lo)) {
one=true;
}
if(isHot(hi)) {
two=true;
}
if(!(one||two)) {
return (hi+lo)/2;// equal distance
}
if(two) {
lo=hi-(hi-lo)/2;
continue;//checking two before as it's hotter than lo so ignoring the lo
}
if(one) {
hi=lo+(hi-lo)/2;
}
}
return 0;
}
public static boolean isHot(int curr) {
boolean hot=false;
if(Math.abs(num-curr)<Math.abs(num-prev)) {
hot=true;
}
prev=curr;
return hot;
}
}
Given k, we need to write 1 as a sum of k fractions of the form 1/r.
For example,
For k=2, 1 can uniquely be written as 1/2 + 1/2.
For k=3, 1 can be written as 1/3 + 1/3 + 1/3 or 1/2 + 1/4 + 1/4 or 1/6 + 1/3 + 1/2
Now, we need to consider all such set of k fractions that sum upto 1 and return the highest denominator among all such sets; for instance, the sample case 2, our algorithm should return 6.
I came across this problem in a coding competition and couldn't come up with an algorithm for the same. A bit of Google search later revealed that such fractions are called Egyption Fractions but probably they are set of distinct fractions summing upto a particular value (not like 1/2 + 1/2). Also, I couldn't find an algo to compute Egyption Fractions (if they are at all helpful for this problem) when their number is restricted by k.
If all you want to do is find the largest denominator, there's no reason to find all the possibilities. You can do this very simply:
public long largestDenominator(int k){
long denominator = 1;
for(int i=1;i<k;i++){
denominator *= denominator + 1;
}
return denominator;
}
For you recursive types:
public long largestDenominator(int k){
if(k == 1)
return 1;
long last = largestDenominator(k-1);
return last * (last + 1); // or (last * last) + last)
}
Why is it that simple?
To create the set, you need to insert the largest fraction that will keep it under 1 at each step(except the last). By "largest fraction", I mean by value, meaning the smallest denominator.
For the simple case k=3, that means you start with 1/2. You can't fit another half, so you go with 1/3. Then 1/6 is left over, giving you three terms.
For the next case k=4, you take that 1/6 off the end, since it won't fit under one, and we need room for another term. Replace it with 1/7, since that's the biggest value that fits. The remainder is 1/42.
Repeat as needed.
For example:
2 : [2,2]
3 : [2,3,6]
4 : [2,3,7,42]
5 : [2,3,7,43,1806]
6 : [2,3,7,43,1807,3263442]
As you can see, it rapidly becomes very large. Rapidly enough that you'll overflow a long if k>7. If you need to do so, you'll need to find an appropriate container (ie. BigInteger in Java/C#).
It maps perfectly to this sequence:
a(n) = a(n-1)^2 + a(n-1), a(0)=1.
You can also see the relationship to Sylvester's sequence:
a(n+1) = a(n)^2 - a(n) + 1, a(0) = 2
Wikipedia has a very nice article explaining the relationship between the two, as pointed out by Peter in the comments.
I never heard of Egyptian fractions before but here are some thoughts:
Idea
You can think of them geometrically:
Start with a unit square (1x1)
Draw either vertical or horizontal lines dividing the square into equal parts.
Repeat optionally the drawing of lines inside any of the sub-boxes evenly.
Stop any time you want.
The rectangles present will form a set of fractions of the form 1/n that add to 1.
You can count them and they might equal your 'k'.
Depending on how many equal sections you divided a rectangle into, it will tell whether you have 1/2 or 1/3 or whatever. 1/6 is 1/2 of 1/3 or 1/3 of 1/2. (i.e. You dived by 2 and then one of the sub-boxes by 3 OR the other way around.)
Idea 2
You start with 1 box. This is the fraction 1/1 with k=1.
When you sub-divide by n you add n to the count of boxes (k or of fractions summed) and subtract 1.
When you sub-divide any of those boxes, again, subtract 1 and add n, the number of divisions. Note that n-1 is the number of lines you drew to divide them.
More
You are going to start searching for the answer with k. Obviously k * 1/k = 1 so you have one solution right there.
How about k-1?
There's a solution there: (k-2) * 1/(k-1) + 2 * (1/((k-1)*2))
How did I get that? I made k-1 equal sections (with k-2 vertical lines) and then divided the last one in half horizontally.
Each solution is going to consist of:
taking a prior solution
using j less lines and some stage and dividing one of the boxes or sub-boxes into j+1 equal sections.
I don't know if all solutions can be formed by repeating this rule starting from k * 1/k
I do know you can get effective duplicates this way. For example: k * 1/k with j = 1 => (k-2) * 1/(k-1) + 2 * (1/((k-1)*2)) [from above] but k * 1/k with j = (k-2) => 2 * (1/((k-1)*2)) + (k-2) * 1/(k-1) [which just reverses the order of the parts]
Interesting
k = 7 can be represented by 1/2 + 1/4 + 1/8 + ... + 1/(2^6) + 1/(2^6) and the general case is 1/2 + ... + 1/(2^(k-1)) + 1/(2^(k-1)).
Similarly for any odd k it can be represented by 1/3 + ... + 3 * [1/(3^((k-1)/2)].
I suspect there are similar patterns for all integers up to k.