Finding minimum number of days - algorithm

I got this question as a part of the interview and I am still unable to solve it.
It goes like this
A person has to complete N units of work; the nature of work is the same.
In order to get the hang of the work, he completes only one unit of work in the first day.
He wishes to celebrate the completion of work, so he decides to complete one unit of work in the last day.
Given that he is only allowed to complete x, x+1 or x-1 units of work in a day, where x is the units of work
completed on the previous day.
How many minimum days will he take to complete N units of work?
Sample Input:
6
-1
0
2
3
9
13
Here, line 1 represents the number of input test cases.
Sample Output:
0
0
2
3
5
7
Each number represents the minimum days required for each input in the sample input.
I tried doing it using the coin change approach but was not able to do so.

In 2k days, it's possible to do at most 2T(k) work (where T(k) is the k'th triangular number). In 2k+1 days, it's possible to do at most T(k+1)+T(k) at most work. That's because if there's an even (2k) number of days, the most work is 1+2+3+...+k + k+(k-1)+...3+2+1. Similarly, if there's an odd (2k+1) number of days, the most work is 1+2+3+...+k+(k+1)+k+...+3+2+1.
Given this pattern, it's possible to reduce the amount of work to any value (greater than 1) -- simply reduce the work done on the day with the most work, never picking the start or end day. This never invalidates the rule that the amount of work on one day is never more than 1 difference from an adjacent day.
Call this function F. That is:
F(2k) = 2T(k)
F(2k+1) = T(k)+T(k+1)
Recall that T(k) = k(k+1)/2, so the equations simplify:
F(2k) = k(k+1)
F(2k+1) = k(k+1)/2 + (k+1)(k+2)/2 = (k+1)^2
Armed with these observations, you can solve the original problem by finding the smallest number of days where it's possible to do at least N units of work. That is, the smallest d such that F(d) >= N.
You can, for example, use binary search to find d, or an optimal approach is to solve the equations. The minimal even solution has d/2 * (d/2 + 1) >= N which you can solve as a quadratic equation, and the minimal odd solution has (d+1)^2/4 >= N, which has a solution d = ceil(2sqrt(N)-1). Once you've found the minimal even and odd solutions, then you can pick the smaller of the two.

AS you want to have the minimum amounts of days you can just say yeah x+1, since if you want the minimum amount of days, BUT you have to consider that his last day x should be 1 so you have to break at a given point and go x-1, so now we have to determine the Breakpoint.
The Breakpoint is located in the middle of the days, since you start at 1 and want to end at 1.
For example you have to do 16 units so you distribute your days like:
Work done:
1234321.
7 days worked.
When you can't make an even Breakpoint like above repeat some values
5 = 1211
Samples:
2: 11
3: 111
9: 12321
13: 1234321

If you need to do exactly N units, not more, then you could use dynamic programming on the matrix a[x][y] where x is the amount of work done in the last day, y is the total amount of work, and a[x][y] is the the minimum number of days needed. You could use Dijkstra's algorithm to minimize a[1][N]. Begin with a[1][1]=1.

Related

find max sum in array with fixed number of turns and initial position

This is a problem i had in a test, and i didn't know how to answer it, so i forward this to you guys:
Find a polynomial time algorithm this problem:
You get an array of N positive integers (with fixed range) , a starting position (number between 0 to N-1),and a fixed number of turns.
In each turn, one can decide if to take the array[where he stand on now] and add it to a sum (and then you need to remember that this cell is empty), or to skip , and go left or right.
You need to find the maximum sum we can get.
for example:
array = {70,3,100}
STARTING_POSITION = 2
TURNS = 4
the output : 170
turn 1 - take the 100 , turn 2 - move left, turn 3 - move left,turn 4 - take the 70.
I thought about dynamic programming but i didn't know to deal with the cells i already took - this influence on the whole table for this approach.

How to find the minimum time required to solve all N problems?

I was trying to solve this problem but even after hours I am not able
to understand the problem completely. I am not even able to come up
with any brute force techniques.This is the question:
There are N members and N problems and each member must exactly solve
1 problem.Only one member of the from the team is allowed to read the
problem statements before anyone start to solve.
Note that not everyone have read the problems at first. So, to solve
problems a member needs to know the statements from some teammate who
already knows them. After knowing problems once, a member is eligible
to explain them to other teammates ( one teammate at a time ). You can
assume that the explaining ( 1 or N problems ) will always take D
minutes. During explaining, none of the two involved members will be
able to do anything else.
Problems are of different difficulty levels. You can assume that it
will take Ti minutes to solve the ith problem, regardless of which
member solves it.
Given a team's data, what is the minimum possible time in which they
can solve all problems?
Input
N D
2 100
T=[1 2]
Output
102
Member 1 is allowed to know problems before start time. He starts
explaing problems to member 2 when contest starts. Explaining ends at
the 100th minute. Then both of them immidiately starts solving
problems parallely. Member 1 solved 1st problem at the 101th minute
and member 2 solved 2nd problem at the 102th minute.
What is the best method to decode this type of problem and to approach it?
This reminds me of Huffman coding.
I am not sure if the following approach is optimal, but it will probably give a good answer in practice.
Pick the easiest two problems T0 and T1 and replace them by a single problem consisting of time D+max(T0,T1).
Repeat until you have a single problem left
Finding the two easiest problems can be done in O(logN) if you store the problems in a binary heap, so overall this is O(NlogN).
Example
Suppose we have 1,3,4,6 and D=2.
We first combine 1 and 3 to make 2+max(1,3)=5. The new list is 4,5,6
We then combine 4 and 5 to make 2+max(4,5)=7. The new list is 6,7.
We then combine 6 and 7 to make 2+max(6,7)=9.
This represents the following procedure.
t=0 A shares with B
t=2 A starts problem 6, B shares with C
t=4 B starts problem 4, C shares with D
t=6 C starts problem 3, D starts problem 1
t=7 D finishes
t=8 A finishes, B finishes
t=9 C finishes
Every member of the team (except the one who read the problems)
must hear the problems. That is, problems must be told N - 1 times.
For N = 2 this can be done in D minutes,
for 2 < N <= 4 in 2D minutes,
for 4 < N <= 8 in 3D minutes, etc.
If N is not an exact power of 2 then some people must finish telling
the problems at least D minutes sooner than others.
The ones who finish early can work on
the hardest problems, leaving easier problems for the ones who finish later.
If some of the problems take time Ti > D and N is neither an exact
power of 2 nor one less than an exact power of 2, you may want to have
someone stop telling problems more than D minutes before
the last problem-telling is finished.
If some of the problems take time Ti > 2D then you may need to consider
making some people stop telling problems and start working on the really
hard problems sooner even if N is an exact power of 2.
Since the solving of one problem is in every member's critical path,
but telling is in multiple members' critical paths,
it makes no sense for anyone to solve a problem until they are finished
with all the telling of problems they are going to do.
After each D minutes the number of people who know the problems
increases by the number who were telling problems.
The number who are telling problems increases by the number who
were telling problems (that is, the number who have just learned the
problems) minus the number who start working on problems at that time.
A good "brute force" approach might be to sort the problems
by difficulty; then find out the time until the last person hears
the problems if nobody starts working on them before then;
find out when the last person finishes;
then try starting problems D minutes earlier, or 2D minutes,
or 3D minutes, etc., but never start a shorter-running
problem before a longer-running one.
The problem statement is somewhat ambiguous about the explaining part. Depending on how the statement is interpreted, the following solution is possible:
If you assume that you can explain N problems in D minutes, then it takes N/D minutes to explain one problem. Let's call that Te, for "time to explain". And the time to solve Problem i is Ti, which we know is equal to i minutes.
So at the start of the contest, Member 1 (who knows all of the problems) explains problem N to Member 2. That takes Te minutes. Member 2 then begins working on problem N (which will take N minutes to solve), and Member 1 starts explaining problem N-1 to Member 3. This continues until Member 1 explains problem 2 to Member N. At that point, Member N starts working on problem 2, and Member 1 starts working on problem 1.
Let's say that there are 4 problems, 4 team members, and D=8. So Te=2.
Time Description
0 Member 1 begins explaining Problem 4 to Member 2
2 Member 2 begins working on Problem 4
Member 1 begins explaining Problem 3 to Member 3
4 Member 3 begins working on Problem 3
Member 1 begins explaining Problem 2 to Member 4
6 Member 2 completes problem 4
Member 4 begins working on Problem 2
Member 1 begins working on Problem 1
7 Member 3 completes Problem 3
Member 1 completes Problem 1
8 Member 4 completes Problem 2
This seems like the optimum solution regardless of the value of D or N: arrange it so that the problem that takes the longest to solve is started as early as possible.
I suspect that the problem statement is an English translation of a problem given in some other language or perhaps a re-translation of something that was originally written in English and translated into some other language. Because if that's the original problem statement, whoever wrote it should be barred from ever writing problems again.
The length of time it takes to complete any one task seems of the form C * D + T, where C is a positive integer less than N, and all N-1 lead-times must be accounted for. Suppose we made a mistake and the optimal solution should actually have a task coupled with a longer lead time - so some C * D + Tj < C * D + Ti, where Ti < Tj, which is impossible.
Therefore, iterate once over the sums of pairs (assuming sorted input):
solution = maximum (T2 + (n-1) * D, T3 + (n-2) * D...D + Tn)

Algorithm for rope burning

Generalized from a technical interview question:
Original question: There are two ropes, each rope takes 1 hour to
burn. But either rope has different densities at different points, so
there’s no guarantee of consistency in the time it takes different
sections within the rope to burn.
How do you use these two ropes to measure 45 minutes?
I have a generalized version:
There are n ropes, each rope takes x minutes to
burn (for simplicity assume x is positive integer). But the ropes have different densities at different points, so
there’s no guarantee of consistency in the time it takes different
sections within the ropes to burn.
Using these n ropes, what time quantity can you measure?
For example, with n = 1 and x = 60, I can measure 60 minute period
(burning one end of the rope), or 30 minute period (burning both ends
of the rope at the same time)
Of course my aim would be finding an algorithm with minimal complexity. I imagine the solution to this would involve dynamic programming, but I am not quite sure. My brute force solution is as followed:
Start at minute 0, we have n ropes, each takes x minutes to burn. For a given rope, we have choices either to burn both ends, one end, or not burning the rope at all. Let number of ropes that will not be burnt at this stage be x, number of ropes that will be burnt one end be y, and number of ropes that will not be burnt at all be z. We have x + y + z = n and that x,y,z are positive integers and z != 0. Consider all possible cases for x, y and z and add those cases to a stack/queue.
For each item in the stack/queue, determine how many minutes have passed when there is a rope finishes burning. Output the time that has passed (calculated based on how long the finished rope has burnt, and which ends were burnt at what time). Now we have another scenarios with certain amount of ropes that are being burnt. Repeat the step 1 argument with x + y + z = n - 1 (with constraints imposed on x, y, and z since some ropes are still burning and we cannot set the fire off) and add all the newly generated cases to the stack/queue.
Repeat 2. until n = 0 (All ropes finished burning)
Edit:
For n = 2 and x = 60, I've found that the following time period can be measured: 30, 60, 90, 120, 45 and 15.
As suggested, I posted the question on cs.stackexchange.com: https://cs.stackexchange.com/questions/32455/algorithm-for-rope-burning-problem
Well, here is my attempt to solve the problem with greater efficiency. I might have overlooked something, so be wary even if it seems to make sense.
We can start with a base state of 1 rope yields x minutes or x/2 minutes. Now, suppose it is possible to measure x_prev minutes with n ropes. Then, consider what happens if we add the n+1th rope. We can
Wait for the whole x_prev minutes to expire, then burn the next rope from 1 end. This means we can achieve x_prev + x minutes.
Wait for the whole x_prev minutes to expire, then burn the next rope from 2 ends. This means we can achieve x_prev + x/2 minutes.
Start burning the x_prev minutes as we burn the next rope from 1 end. This means we can achieve abs( x - x_prev ) minutes.
Start burning the x_prev minutes as we burn the next rope from 2 ends. This means we can achieve abs( x/2 - x_prev) minutes.
We do not care about a time t that was achieved with m with m<=n-1 ropes because we would have considered these four cases when we were adding the m+1-th rope.
These seem like the only four cases. So, in pseudocode, perhaps something like this
let solutions be a list of measurable times
def solve( n , x ):
if n <= 0
return, you cannot measure any times
else
#set up base case n=1
append x/2 and x to solutions
#we can be efficient by only checking the times achievable with n-1 ropes
#we will store the index of the first time that was recorded with n-1 ropes
#in start_idx
let start_idx be an index in the solutions array
#assume the array indices start at 0. then start_idx is the index
#of the first recorded time measurable with 1 rope.
start_idx = 0
#then continuously add additional ropes until we have n ropes
for i in 2..n
let solutions_to_add be a list
for j in start_idx..solutions.size() - 1
if solutions does not contain time+x
append time+x to solutions_to_add
if solutions does not contain time+x/2
append time+x/2 to solutions_to_add
if solutions does not contain abs( x-time )
append abs( x-time ) to solutions_to_add
if solutions does not contain abs( x/2-time )
append abs( x/2-time ) to solutions_to_add
#update the start_idx to be the starting index of times achievable with
#i ropes
start_idx = solutions.size()
#then add the achievable times with i ropes
for each time in solutions_to_add
append time to solutions
You can probably get O(1) run time for solution contains by using a boolean array for lookup. The overall algorithm seems to be O(n^2).
Is it correct? I'm not really sure if my four cases cover everything. I am pretty sure the induction-like process is correct.

Find the smallest set group to cover all combinatory possibilities

I'm making some exercises on combinatorics algorithm and trying to figure out how to solve the question below:
Given a group of 25 bits, set (choose) 15 (non-permutable and order NON matters):
n!/(k!(n-k)!) = 3.268.760
Now for every of these possibilities construct a matrix where I cross every unique 25bit member against all other 25bit member where
in the relation in between it there must be at least 11 common setted bits (only ones, not zeroes).
Let me try to illustrate representing it as binary data, so the first member would be:
0000000000111111111111111 (10 zeros and 15 ones) or (15 bits set on 25 bits)
0000000001011111111111111 second member
0000000001101111111111111 third member
0000000001110111111111111 and so on....
...
1111111111111110000000000 up to here. The 3.268.760 member.
Now crossing these values over a matrix for the 1 x 1 I must have 15 bits common. Since the result is >= 11 it is a "useful" result.
For the 1 x 2 we have 14 bits common so also a valid result.
Doing that for all members, finally, crossing 1 x 3.268.760 should result in 5 bits common so since it's < 11 its not "useful".
What I need is to find out (by math or algorithm) wich is the minimum number of members needed to cover all possibilities having 11 bits common.
In other words a group of N members that if tested against all others may have at least 11 bits common over the whole 3.268.760 x 3.268.760 universe.
Using a brute force algorithm I found out that with 81 25bit member is possible achive this. But i'm guessing that this number should be smaller (something near 12).
I was trying to use a brute force algorithm to make all possible variations of 12 members over the 3.268.760 but the number of possibilities
it's so huge that it would take more than a hundred years to compute (3,156x10e69 combinations).
I've googled about combinatorics but there are so many fields that i don't know in wich these problem should fit.
So any directions on wich field of combinatorics, or any algorithm for these issue is greatly appreciate.
PS: Just for reference. The "likeness" of two members is calculated using:
(Not(a xor b)) and a
After that there's a small recursive loop to count the bits given the number of common bits.
EDIT: As promissed (#btilly)on the comment below here's the 'fractal' image of the relations or link to image
The color scale ranges from red (15bits match) to green (11bits match) to black for values smaller than 10bits.
This image is just sample of the 4096 first groups.
tl;dr: you want to solve dominating set on a large, extremely symmetric graph. btilly is right that you should not expect an exact answer. If this were my problem, I would try local search starting with the greedy solution. Pick one set and try to get rid of it by changing the others. This requires data structures to keep track of which sets are covered exactly once.
EDIT: Okay, here's a better idea for a lower bound. For every k from 1 to the value of the optimal solution, there's a lower bound of [25 choose 15] * k / [maximum joint coverage of k sets]. Your bound of 12 (actually 10 by my reckoning, since you forgot some neighbors) corresponds to k = 1. Proof sketch: fix an arbitrary solution with m sets and consider the most coverage that can be obtained by k of the m. Build a fractional solution where all symmetries of the chosen k are averaged together and scaled so that each element is covered once. The cost of this solution is [25 choose 15] * k / [maximum joint coverage of those k sets], which is at least as large as the lower bound we're shooting for. It's still at least as small, however, as the original m-set solution, as the marginal returns of each set are decreasing.
Computing maximum coverage is in general hard, but there's a factor (e/(e-1))-approximation (≈ 1.58) algorithm: greedy, which it sounds as though you could implement quickly (note: you need to choose the set that covers the most uncovered other sets each time). By multiplying the greedy solution by e/(e-1), we obtain an upper bound on the maximum coverage of k elements, which suffices to power the lower bound described in the previous paragraph.
Warning: if this upper bound is larger than [25 choose 15], then k is too large!
This type of problem is extremely hard, you should not expect to be able to find the exact answer.
A greedy solution should produce a "fairly good" answer. But..how to be greedy?
The idea is to always choose the next element to be the one that is going to match as many possibilities as you can that are currently unmatched. Unfortunately with over 3 million possible members, that you have to try match against millions of unmatched members (note, your best next guess might already match another member in your candidate set..), even choosing that next element is probably not feasible.
So we'll have to be greedy about choosing the next element. We will choose each bit to maximize the sum of the probabilities of eventually matching all of the currently unmatched elements.
For that we will need a 2-dimensional lookup table P such that P(n, m) is the probability that two random members will turn out to have at least 11 bits in common, if m of the first n bits that are 1 in the first member are also 1 in the second. This table of 225 probabilities should be precomputed.
This table can easily be computed using the following rules:
P(15, m) is 0 if m < 11, 1 otherwise.
For n < 15:
P(n, m) = P(n+1, m+1) * (15-m) / (25-n) + P(n+1, m) * (10-n+m) / (25-n)
Now let's start with a few members that are "very far" from each other. My suggestion would be:
First 15 bits 1, rest 0.
First 10 bits 0, rest 1.
First 8 bits 1, last 7 1, rest 0.
Bits 1-4, 9-12, 16-23 are 1, rest 0.
Now starting with your universe of (25 choose 15) members, eliminate all of those that match one of the elements in your initial collection.
Next we go into the heart of the algorithm.
While there are unmatched members:
Find the bit that appears in the most unmatched members (break ties randomly)
Make that the first set bit of our candidate member for the group.
While the candidate member has less than 15 set bits:
Let p_best = 0, bit_best = 0;
For each unset bit:
Let p = 0
For each unmatched member:
p += P(n, m) where m = number of bits in common between
candidate member+this bit and the unmatched member
and n = bits in candidate member + 1
If p_best < p:
p_best = p
bit_best = this unset bit
Set bit_best as the next bit in our candidate member.
Add the candidate member to our collection
Remove all unmatched members that match this from unmatched members
The list of candidate members is our answer
I have not written code, I therefore have no idea how good an answer this algorithm will produce. But assuming that it does no better than your current, for 77 candidate members (we cheated and started with 4) you have to make 271 passes through your unmatched candidates (25 to find the first bit, 24 to find the second, etc down to 11 to find the 15th, and one more to remove the matched members). That's 20867 passes. If you have an average of 1 million unmatched members, that's on the order of a 20 billion operations.
This won't be quick. But it should be computationally feasible.

Arranging groups of people optimally

I have this homework assignment that I think I managed to solve, but am not entirely sure as I cannot prove my solution. I would like comments on what I did, its correctness and whether or not there's a better solution.
The problem is as follows: we have N groups of people, where group ihas g[i]people in it. We want to put these people on two rows of S seats each, such that: each group can only be put on a single row, in a contiguous sequence, OR if the group has an even number of members, we can split them in two and put them on two rows, but with the condition that they must form a rectangle (so they must have the same indices on both rows). What is the minimum number of seats S needed so that nobody is standing up?
Example: groups are 4 11. Minimum S is 11. We put all 4 in one row, and the 11 on the second row. Another: groups are 6 2. We split the 6 on two rows, and also the two. Minimum is therefore 4 seats.
This is what I'm thinking:
Calculate T = (sum of all groups + 1) / 2. Store the group numbers in an array, but split all the even values x in two values of x / 2 each. So 4 5 becomes 2 2 5. Now run subset sum on this vector, and find the minimum value higher than or equal to T that can be formed. That value is the minimum number of seats per row needed.
Example: 4 11 => 2 2 11 => T = (15 + 1) / 2 = 8. Minimum we can form from 2 2 11 that's >= 8 is 11, so that's the answer.
This seems to work, at least I can't find any counter example. I don't have a proof though. Intuitively, it seems to always be possible to arrange the people under the required conditions with the number of seats supplied by this algorithm.
Any hints are appreciated.
I think your solution is correct. The minimum number of seats per row in an optimal distribution would be your T (which is mathematically obvious).
Splitting even numbers is also correct, since they have two possible arrangements; by logically putting all the "rectangular" groups of people on one end of the seat rows you can also guarantee that they will always form a proper rectangle, so that this condition is met as well.
So the question boils down to finding a sum equal or as close as possible to T (e.g. partition problem).
Minor nit: I'm not sure if the proposed solution above works in the edge case where each group has 0 members, because your numerator in T = SUM ALL + 1 / 2 is always positive, so there will never be a subset sum that is greater than or equal to T.
To get around this, maybe a modulus operation might work here. We know that we need at least n seats in a row if n is the maximal odd term, so maybe the equation should have a max(n * (n % 2)) term in it. It will come out to max(odd) or 0. Since the maximal odd term is always added to S, I think this is safe (stated boldly without proof...).
Then we want to know if we should split the even terms or not. Here's where the subset sum approach might work, but with T simply equal to SUM ALL / 2.

Resources