Formulating a knapsack style solution for spoj "BEHAPPY"? - algorithm

The problem is described at problem ,I have been trying to reach an iterative dp solution to the above problem.
What i can guess from my experience in coding is ,it should have three dimensions, each state uniquely identified by :-
M = Gifts not distributed yet.
N = first N girlfriends available (Similar to 0-1 Knapsack)
C = Maximum gifts allowable for current girlfriend.
Now initializing for M=0,N,C (i.e. When 0 gifts remain to be distributed)
1 2 3 4 (girlfriends)
0
1
2
3
(Capacity)
I seem to have a problem , with initialization at k=0 as there is a low and high gift limit both for girlfriends ,hence deviating from standard knapsack having only maximum limit(not considering that knapsack finds optimum solution,and here i consider all possible solution)
Of course i maybe completely on the wrong path here ,if you feel is the case, what is the recurrence and initialization for this 3 state variable dp?
Thanks in advance

First remove all the minimum requirements. M -= sum(A[i]) and B[i] -= A[i]. These are the minimum so there's nothing for us to move around, just assign them and take them out of the computation.
Now your solution matrix sol[g, m] is the number of ways you can solve the first g girlfriends while having m gifts left. sol[g,m] = sum(sol[g-1, m-j], j= [0..B[g-1]]. You initialize sol[0, M] with 1 and the rest is 0.
Your solution will be sol[N+1, 0].
You only need the last line if you do it iteratively.

Related

Proving the greedy solution to the weighted task scheduling problem

I am attempting to prove the following algorithm is fully correct (partial correctness + termination), but I can only seem to prove for arbitrary example inputs (not general ones).
Here is my pseudo-code:
IN :Listofjobs J, maxindex n
1:S ← an array indexed 0 to n, with null at each index
2:Sort J in non-increasing order of profits
3:for i from 0 to n
4:Find the largest t such that S[t] = null and t ≤ J[i].deadline (if one exists) if an index t was found
5: S[t] ← J[i]
OUT: S maximizes the profit of scheduled jobs that can be done in n 1 unit of time blocks
So for example, I created a table with jobs and their associated attributes (deadlines and profit):
jOB J1 J2 J3 J4 J5
Deadline 2 1 3 2 1
profit 62 100 20 40 20
From this example input, we'd be able to do J2,J1,J3 for a total profit of 182.
Can someone help me form a more generic way of showing my pseudo-code algorithm is fully correct?
Adding constraints helps you here.
In step 2 order J first by non-increasing profits, and then by non-increasing deadline.
Of all optimal solutions, at least one must be lexicographically last by the ordering of profits of jobs over time. (If multiple jobs have the same profit and deadlines, there may be multiple optimal solutions that are lexicographically last.)
Prove that any solution that does not have a job of the same profit at the same time as the first job that you place is either not optimal, or is not lexicographically last among optimal solutions.
Prove by induction that the solution that you found is identical in placement of sizes of jobs as any solution that is optimal and lexicographically last among optimal solutions.
Please note that this is an outline only. There are some subtle tricks needed at each step of this proof that I'm deliberately leaving as an exercise.

Solving problems with formulas (GCD and LCM)

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).

Number of ways to represent a number as a sum of K numbers in subset S

Let the set S be {1 , 2 , 4 , 5 , 10}
Now i want to find the number of ways to represent x as sum of K numbers of the set S. (a number can be included any number of times)
if x = 10 and k = 3
Then the ans should be 2 => (5,4,1) , (4,4,2)
The order of the numbers doesn't matter ie.(4,4,2) and (4,2,4) count as one.
I did some research and found that the set can be represented as a polynomial x^1+x^2+x^4+x^5+x^10 and after raising the polynomial to the power K the coefficients of the product polynomial gives the ans.
But the ans includes (4,4,2) and (4,2,4) as unique terms which i don't want
Is there any way to make (4,4,2) and (4,2,4) count as same term ?
This is a NP-complete, a variant of the sum-subset problem as described here.
So frankly, I don't think you can solve it via a non-exponential (iterate though all combinations) solution, without any restrictions on the problem input (such as maximum number range, etc.).
Without any restrictions on the problem domain, I suggest iterating through all your possible k-set instances (as described in the Pseudo-polynomial time dynamic programming solution) and see which are a solution.
Checking whether 2 solutions are identical is nothing compared to the complexity of the overall algo. So, a hash of the solution set-elements will work just fine:
E.g. hash-order-insensitive(4,4,2)==hash-order-insensitive(4,2,4) => check the whole set, otherwise the solutions are distinct.
PS: you can also describe step-by-step your current solution.

scheduling n people with given time of travel

this is a puzzle but i think it could be a classical algorithm which i am unaware of :
There are n people at the bottom of a mountain, and everyone wants to go up, then down the mountain. Person i takes u[i] time to climb this mountain, and d[i] time to descend it.
However, at same given time atmost 1 person can climb , and .atmost 1 person can descend the mountain. Find the least time to travel up and back down the mountain.
Update 1 :
well i tried with few examples and found that it's not reducible to sorting , or getting the fastest climbers first or vice versa . I think to get optimal solution we may have to try out all possible solutions , so seems to be NP complete.
My initial guess: (WRONG)
The solution i thought is greedy : sort n people by start time in ascending order. Then up jth person up and kth down where u[j]<= d[k] and d[k] is minimum from all k persons on top of mountain. I am not able to prove correctness of this .
Any other idea how to approach ?
A hint would suffice.
Try to think in the following manner: if the people are not sorted in ascending order of time it takes them to climb the mountain than what happens if you find a pair of adjacent people that are not in the correct order(i.e. first one climbs longer than second one) and swap them. Is it possible that the total time increases?
I think it is incorrect. Consider
u = [2,3]
d = [1,3]
Your algorithm gives ordering 0,1 whereas it should be 1,0.
I would suggest another greedy approach:
Create ordering list and add first person.
For current ordering keep track of two values:
mU - time of last person on the mountain - time of the end
mD - time of earliest time of first descending
From people who are not ordered choose the one which minimises abs(mD - d) and abs(mU - u). Then if abs(mD - d) < abs(mU - u) he should go at the beginning of ordering. Otherwise he goes at the end.
Some tweak may still be needed here, but this approach should minimise losses from cases like the one given in the example.
The following solution will only work with n <= 24.
This solution will require dynamic programming and bit-mask technique knowledge to be understood.
Observation: we can easily observe that the optimal total climb up time is fixed, which is equalled to the total climb up time of n people.
For the base case, if n = 1, the solution is obvious.
For n = 2, the solution is simple, just scan through all 4 possibilities and calculate the minimum down time.
For n = 3, we can see that this case will be equal to the case when one person climb up first, followed by two.
And the two person minimum down time can be easily pre-calculated. More important, this two person then can be treated as one person with up time is the total up time of the two, and down time is the minimum down time.
Storing all result for minimum down time for cases from n = 0 to n = 3 in array called 'dp', using bit-mask technique, we represent the state for 3 person as index 3 = 111b, so the result for case n = 3 will be:
for(int i = 0; i < 3; i++){
dp[3] = min(dp[(1<<i)] + dp[3^(1<<i)],dp[3]);
}
For n = 4... 24, the solution will be similar to case n = 3.
Note: The actual formula is not just simple as the code for case n = 3(and it requires similar approach to solve as case n = 2), but will be very similar,
Your approach looks sensible, but it may be over-simplified, could you describe it more precisely here?
From your description, I can't make out whether you are sorting or something else; these are the heuristics that I figured you are using:
Get the fastest climbers first, so the start using the Down path
asap.
Ensure there is always people at the top of the mountain, so
when the Down path becomes available, a person starts descending
immediately.The way you do that is to select first those people who
climb fast and descend slowly.
What if the fastest climber is also the fastest descender? That would leave the Down path idle until the second climber gets to the top, how does your algorithm ensures that this the best order?. I'm not sure that the problem reduces to a Sorting problem, it looks more like a knapsack or scheduling type.

Resource allocation- Matching

I've got a problem which I'm not sure can be solved by Linear Programming. Essentially there are 2 groups of people who are list their preference for one another and will be subsequently matchd. I'm writing an algorithm for this. Group A has upto 4 choices from Group B and vice versa.
In formulating a solution, I am currently assigning a cost to each combination of pairs. For example if Person 1 from Group A ranks Person 3 from Group B as his/her number 1 choice and vice versa, then the cost is minimal (Pair 1-3 cost: 0.01). Similarly, I would allot a cost to other pairs, devising an objective function which seeks to have pairings which minimize overall cost.
However, I do not see this being feasible because I don't know how to define my constraints and overall objective function. Reading online and from textbooks, I find resource allocation problems to be different from what I am trying to do.
Can I seek your advise on how to proceed?
Your problem can be formulated as an "Assignment Problem." As a canonical case, assignment problems are for assigning "jobs" to "machines." They can just as easily be used for Matching two sets.
Here's the formulation:
Two sets of people A and B
Decision Variable Xij
Let Xij be 1 if person i (ith person in set A) is matched with jth person in set B; 0 otherwise
Parameters:
Let Cij be the cost of pairing person i with person j
Objective Function: Minimize (Sum over i) (sum over j) Cij * Xij
Constraints:
Every Person i gets paired exactly once
Sum over j Xij = 1 (for each i)
Every Person j gets paired exactly once
Sum over i Xij = 1 (for each j)
Xij are Binary variables
Xij = (0,1)
The neat thing about Assignment problems is that the optimal pairings can be found using the fairly easy to understand 'Hungarian Method.' You can also use an LP/IP solver you have at your disposal.
Hope that helps.

Resources