PartitionProblem - find the optimal subsets - algorithm

I need to find the optimal subsets after solving the partition problem using the Dynamic Programming pseudo polynomial time algorithm.
More specifically, I'm not able to make sense of this answer: https://stackoverflow.com/a/890243/1317826
I'm not able to understand how to construct the optimal subsets from the boolean table.
The Wikipedia article on the partition problem has it too: http://en.wikipedia.org/wiki/Partition_problem
Can someone please shed some light on it?

Everything you need is in the answer you posted.
First of all, when you create table using pseudo-polynomial time algorithm you don't store boolean values (True if it's reachable, False otherwise), but value of the element that you added to the subset. Than you should be able to construct subset by simply substracting it from the sum you obtained.
So the algorithm is:
For every number x_i in your set:
Set p(1, x_i) = x_i
For every other field p(row, sum) set it to x_i if p(row-1, sum-x_i) != 0
So now p(row, sum) = x means that we can get sum by taking some row elements of our set and last one of them is x.
Once p(some_row, N/2) != 0 you can construct the subset by taking it's value x, and moving to p(some_row - 1, N/2 - x) and so forth.
Hope this makes it clear.
BTW. Is there a way to write latex in the answers?

Related

Find minimum steps to convert all elements to zero

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.

Dyanamic Programming - Coin Change Problem

I am solving the following problem from hackerrank
https://www.hackerrank.com/challenges/coin-change/problem
I 'm unable to solve the problem , so I have looked at the editorial and they mentioned
T(i, m) = T(i, m-i)+T(i+1, m)
I'm unable to get big picture of why this solution works on a higher level. (like a proof in CLRS or simple understandable example)
Solution which I have written is as follows
fun(m){
//base cases
count = 0;
for(i..n){
count+= fun(m-i);
}
}
My solution didn't work because there are some duplicates calls. But how editorial works and what is the difference between my solution and editorial on a higher level..
I think in order for this to work you have to clearly define what T is. Namely, let's define T(i,m) to be the number of ways to make change for m units using only coins with index at least i (i.e. we only look at the ith coin, the (i+1)th coin, all the way to the nth coin while neglecting the first i-1 coins). Further, we define an array C such that C[i] is the value of the ith coin (note that in general C[i] is not the same as i). As a result, if there are n coins (i.e. length of C is n) and we want to make change for W units, we are looking for the value T(0, W) as our answer (make sure you can see why this is the case at this point!).
Now, we proceed by constructing a recursive definition of T(i,m). Note that our solution will either contain an additional ith coin or it won't. In the case that it does, our new target will simply be m - C[i] and the number of ways to make change for this is T(i,m - C[i]) (since our new target is now C[i] less than m). In another case, our solution doesn't contain the ith coin. In this case, we keep the target value the same, but only consider coins with index greater than i. Namely, the number of ways to make change in this case is T(i+1,m). Since these cases are disjoint and exhaustive (either you put the ith coin in the solution or you don't!), we have that
T(i,m) = T(i, m-C[i]) + T(i+1,m)
which is very similar to what you had (the C[i] difference is important). Note that if m <= 0 (since we are assuming that coin values are positive), there are 0 ways to make change. You must keep these base cases in mind when computing T(i,m).
Now it remains to compute T(0, W), which you can easily do recursively. However, you likely noticed that a lot of the subproblems are repeated making this a slow solution. The solution is to use something called dynamic programming or memoization. Namely, whenever a solution is computed, add its value to a table (e.g. T[i,m] where T is a n x W size 2D array). Then whenever you recursively compute something check the table first so you don't compute the same thing twice. This is called memoization. Dynamic programming is simple except you use a little foresight to compute things in the order in which they will be needed. For example, I would compute the base cases first i.e. the column T[ . , 0]. And then I would compute all values bordering this row and column based on the recursive definition.

Does this algorithm cover all cases for finding minimum coin change for a sum?

I am trying to solve the minimum coin change problem. The question is:
Given a value V, if we want to make change for V cents, and we have infinite supply of each of C = { C1, C2, .. , Cm} valued coins, what is the minimum number of coins to make the change?
My algorithm suggested is:
Starting with an array arr[1..V],where V is the value:
For all the denominations,initialise arr[d]=1 as this is the base case. If the value == demoniation of a coin,only 1 coin is required and hence it is the least
For all values from i : 1...V:
compute the minimum no of coins required to make change for a value of 'i'.
2.1. This can be done by :
For all j: 1....(i-1)
arr[i]=min(arr[i],arr[j]+arr[i-j]);
return arr[V];
Is this logic flawed or does it cover all cases?
Most DP solutions have used a 2-D array and I don't understand why they would use O(n^2) memory space,if this exists and is correct.
Thank u.
How about cases whre some value V cant be obtained?
i.e. we have coins {5,6,7,8,9} and we cant make values 1,2,3,4, You should initialize all value != demoniation cells to infinity constant or something similar.
Now for the reason most people use O(n^2) memory:
This problem comes with various flavors, most common one being you can only use each coin once, in this case using state dp[i][j] - min coins that sum to j after considering first i coins seem to be easier to understand for most people even though this can also be done with O(n) memory (just looping backwards)

Knapsack with unique elements

I'm trying to solve the following:
The knapsack problem is as follows: given a set of integers S={s1,s2,…,sn}, and a given target number T, find a subset of S that adds up exactly to T. For example, within S={1,2,5,9,10} there is a subset that adds up to T=22 but not T=23. Give a correct programming algorithm for knapsack that runs in O(nT) time.
but the only algorithm I could come up with is generating all the 1 to N combinations and try the sum out (exponential time).
I can't devise a dynamic programming solution since the fact that I can't reuse an object makes this problem different from a coin rest exchange problem and from a general knapsack problem.
Can somebody help me out with this or at least give me a hint?
The O(nT) running time gives you the hint: do dynamic programming on two axes. That is, let f(a,b) denote the maximum sum <= b which can be achieved with the first a integers.
f satisfies the recurrence
f(a,b) = max( f(a-1,b), f(a-1,b-s_a)+s_a )
since the first value is the maximum without using s_a and the second is the maximum including s_a. From here the DP algorithm should be straightforward, as should outputting the correct subset of S.
I did find a solution but with O(T(n2)) time complexity. If we make a table from bottom to top. In other words If we sort the array and start with the greatest number available and make a table where columns are the target values and rows the provided number. We will need to consider the sum of all possible ways of making i- cost [j] +j . Which will take n^2 time. And this multiplied with target.

Sum of a number with any k elements in Array

Design an algorithm that, given a set S of n integers and another
integer x, determines whether or not there exist k (n>k>2) elements in
S whose sum is exactly x. Please give the running time of your
algorithm
I have been preparing for an interview, and i have come across this algorithm. I have solved problems where k has been specified in the problem. like 2 or 3. But i cannot find an answer where i might solve for any k that might exist. I have tried solving it using dynamic programming but didn't get results. Can anyone help me on this.
You can make an int array cnt of size x, then go through the set, and mark reachable points. All elements of cnt are set to -1 initially except element zero, which is set to zero.
Repeat the same process for each element si of S: for each element of cnt at position i that is non-negative, check element cnt[i+si] (if it's within the bounds of the array). If it is, set it to cnt[si+i] = max(cnt[i]+1, cnt[si+i]).
Once you go through all elements of S, check cnt[x]. If it is set to two or more, then there exists a combination of two or more elements in S adding up to x.
This algorithm is pseudo-polynomial, with running time O(x*|S|)

Resources