Algorithmic issue - algorithm

I am trying to find a O (n) algorithm for this problem but unable to do so even after spending 3 - 4 hours. The brute force method times out (O (n^2)). I am confused as to how to do it ? Does the solution requires dynamic programming solution ?
http://acm.timus.ru/problem.aspx?space=1&num=1794
In short the problem is this:
There are some students sitting in circle and each one of them has its own choice as to when he wants to be asked a question from a teacher. The teacher will ask the questions in clockwise order only. For example:
5
3 3 1 5 5
This means that there are 5 students and :
1st student wants to go third
2nd student wants to go third
3rd student wants to go first
4th student wants to go fifth
5th student wants to go fifth.
The question is as to where should teacher start asking questions so that maximum number of students will get the turn as they want. For this particular example, the answer is 5 because
3 3 1 5 5
2 3 4 5 1
You can see that by starting at fifth student as 1st, 2 students (3 and 5) are getting the choices as they wanted. For this example the answer is 12th student :
12
5 1 2 3 6 3 8 4 10 3 12 7
because
5 1 2 3 6 3 8 4 10 3 12 7
2 3 4 5 6 7 8 9 10 11 12 1
four students get their choices fulfilled.

It's actually a rather simple problem. If student k wants to be the jth to present, then she will be satisfied iff the (k - j + 1)th (modulo n) is the first to present. This should lead you to a a simple O(n) algorithm.

Related

Can you check for duplicates by taking the sum of the array and then the product of the array?

Let's say we have an array of size N with values from 1 to N inside it. We want to check if this array has any duplicates. My friend suggested two ways that I showed him were wrong:
Take the sum of the array and check it against the sum 1+2+3+...+N. I gave the example 1,1,4,4 which proves that this way is wrong since 1+1+4+4 = 1+2+3+4 despite there being duplicates in the array.
Next he suggested the same thing but with multiplication. i.e. check if the product of the elements in the array is equal to N!, but again this fails with an array like 2,2,3,2, where 2x2x3x2 = 1x2x3x4.
Finally, he suggested doing both checks, and if one of them fails, then there is a duplicate in the array. I can't help but feel that this is still incorrect, but I can't prove it to him by giving him an example of an array with duplicates that passes both checks. I understand that the burden of proof lies with him, not me, but I can't help but want to find an example where this doesn't work.
P.S. I understand there are many more efficient ways to solve such a problem, but we are trying to discuss this particular approach.
Is there a way to prove that doing both checks doesn't necessarily mean there are no duplicates?
Here's a counterexample: 1,3,3,3,4,6,7,8,10,10
Found by looking for a pair of composite numbers with factorizations that change the sum & count by the same amount.
I.e., 9 -> 3, 3 reduces the sum by 3 and increases the count by 1, and 10 -> 2, 5 does the same. So by converting 2,5 to 10 and 9 to 3,3, I leave both the sum and count unchanged. Also of course the product, since I'm replacing numbers with their factors & vice versa.
Here's a much longer one.
24 -> 2*3*4 increases the count by 2 and decreases the sum by 15
2*11 -> 22 decreases the count by 1 and increases the sum by 9
2*8 -> 16 decreases the count by 1 and increases the sum by 6.
We have a second 2 available because of the factorization of 24.
This gives us:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
Has the same sum, product, and count of elements as
1,3,3,4,4,5,6,7,9,10,12,13,14,15,16,16,17,18,19,20,21,22,22,23
In general you can find these by finding all factorizations of composite numbers, seeing how they change the sum & count (as above), and choosing changes in both directions (composite <-> factors) that cancel out.
I've just wrote a simple not very effective brute-force function. And it shows that there is for example
1 2 4 4 4 5 7 9 9
sequence that has the same sum and product as
1 2 3 4 5 6 7 8 9
For n = 10 there are more such sequences:
1 2 3 4 6 6 6 7 10 10
1 2 4 4 4 5 7 9 9 10
1 3 3 3 4 6 7 8 10 10
1 3 3 4 4 4 7 9 10 10
2 2 2 3 4 6 7 9 10 10
My write-only c++ code is here: https://ideone.com/2oRCbh

Algorithm to distribute evenly products value into care packages

i'm currently solving a problem that states:
A company filed for bankruptcy and decided to pay the employees with the last remaining valuable items in the company only if it can be distributed evenly among them so that all of them have at least received 1 item and that the difference between the employee carrying the most valuable items and the employee carrying the least valuable items can not exceed a certain value x;
Input:
First row contains number of employee;
Second row contains the x value so that the the difference between the employee carrying the most valuable items and the employee carrying the least valuable items can not exceed;
Third row contains all the items with their value;
Output:
First number is the least valuable basket of items value and the second is the most valuable basket;
Example:
Input:
5
4
2 5 3 11 4 3 1 15 7 8 10
Output:
13 15
Input:
5
4
1 1 1 11 1 3 1 2 7 8
Output:
NO (It's impossible to distribute evenly)
Input:
5
10
1 1 1 1
Output:
NO (It's impossible to distribute evenly)
My solution to resolve this problem taking the first input is to, sort the items in ascending or descending order so from
2 5 3 11 4 3 1 15 7 8 10 --> 1 2 3 3 4 5 7 8 10 11 15
then create an adjacency list or just store it in simple variables where we add the biggest number to the lowest basket while iterating the item values array
Element 0: 15
Element 1: 11 <- 3 (sum 14)
Element 2: 10 <- 3 (sum 13)
Element 3: 8 <- 4 <- 1 (sum 13)
Element 4: 7 <- 5 <- 2 (sum 14)
So that my solution will have O(nlogN + 2n), first part using merge sort and then finding max e min value, what do you guys think about this solution?

Maximize the minimum score

Given a grid of dimensions A*B with values between 1-9, find a sequence of B numbers that maximizes the minimum number of values matched when compared with A rows.
Describe the certain steps you would take to maximize the minimum score.
Example:
Grid Dimension
A = 5 , B = 10
Grid Values
9 3 9 2 9 9 4 5 7 6
6 3 4 2 8 5 7 5 9 2
4 9 5 8 3 7 3 2 7 6
7 5 8 9 9 4 7 3 3 7
2 6 8 3 2 4 5 4 2 2
Possible Answer
6 3 8 2 9 4 7 5 7 4
Score Calculation
This answer scores
5 when compared with Row 1
5 when compared with Row 2
1 when compared with Row 3
4 when compared with Row 4
2 when compared with Row 5
And thus the minimal score for this answer is 1.
I would go for a local hill-climbing approach that you can complement with a randomization to avoid local minima. Something like:
1. Generate a random starting solution S
2. Compute its score score(S, row) for each row. We'll call min_score(S) the minimum score among all rows for S.
3. Attempt to improve the solution with:
For each digit i (1..B) in S:
If i belongs to a row such that score(S, row) > (min_score(S) + 1) then:
Change i to be the digit of a row with min_score(S). If there was only one row with min_score(S), then min_score(S) has improved by 1
Update the scores of all the rows.
If min_score(S) hasn't improved for more than N iterations of 3, go back to 1 and start with a new random solution.

Genetic Algorithm for Cards

I'm doing an exercise from here(note: not schoolwork!)
It's only my second attempt at a GA, and having issues with the following problem:
How to "reproduce" as in, how do I combine my offspring.
I have a randomly generated population, of which I know the individual fitness(which is a summed distance of the target values).
However, i can't randomly go switching cards between 2 "parents" because which cards can be used is regulated(every card only once for each element in the population).
I hope to get some good feedback from you guys. I can supply additional info if required.
The problem is that every card can be used just once and you have to divide them into two piles, so lets make the problem a bit easier and just use numbers 1-10.
For example take these two solutions:
Parent 1:
1 2 5 7 8 - 3 4 6 9 10
Parent 2:
1 4 5 6 9 - 2 3 7 8 10
In this case, we can't just split them and combine, you'll end up with duplicate numbers. So how do we create healthy children from this? One approach I usually see is to take one of the solutions as 'main' parent.
For example Parent 1, and we take half of the parent:
Child 1:
1 * 5 * 8 - * 4 * 9 *
Child 2:
* 2 * 7 * - 3 * 6 * 10
Next we take our second parent and use it to fill the missing blanks:
Parent 2:
1 4 5 6 9 - 2 3 7 8 10
Child 1:
1 * 5 * 8 - * 4 * 9 *
First we filter out the ones used in child 1:
6 - 2 3 7 10
Next we try to fill the blanks as good as possible:
1 5 6 8 * - 2 3 4 7 9
Now assign the leftovers (they jump side).
The resulting children will be:
Child 1:
1 5 6 8 10 - 2 3 4 7 9
Child 2:
1 2 4 5 7 - 3 6 8 9 10
There are some problems with this idea, namely that for example the 10 in child 1 has jumped sides, and both parents had them in the second pile. This can be countered by first fixating numbers that are the same in both piles.
Just be creative, you'll find a method that works best for your situation.
You can avoid duplicated numbers on offspring chromosomes, as mentioned by #roy-van-rijn, using some crossover operations from TSP (Travelling Salesman Problem). In TSP, children chromosomes cannot duplicate cities too.
Some classic ordered crossover operators:
Cycle Crossover (CX)
Ordered Crossover (OX1)
Partially mapped crossover (PMX)
To keep your cromosomes ordered after mutation, you will need ordered mutation operators too:
Reverse Sequence Mutation (RSM)
Twors mutation

Dropping people in Stata from a panel based on their situation in multiple years

I have an unbalanced panel of 7 years with every person interviewed 4 times and I want to drop all the people that reported that they were unemployed/inactive in all 4 periods. However, I do not want to drop the observations of the people that may have been out of the labour market for 1, 2 or 3 out of the 4 periods they were interviewed. How do I tell Stata to drop people based on their situation in multiple years (t to t-3)? When I do drop if ecostatus>3, for example, Stata drops observations that I need, i.e. the people that were inactive for less than the full period of the survey.
// create some example data
clear
input id t unemp
1 1 1
1 2 1
1 3 1
1 4 1
2 1 1
2 2 0
2 3 1
2 4 1
end
// create the total number of unemployment spells
bys id : egen totunemp = total(unemp)
// display the data
sort id t
list, sepby(id)
// keep those observations with at least one
// employment spell
keep if totunemp < 4
// display the data
list

Resources