but i can not figure out how to write the code , can you please provide a clean code of this !!
I think i got the logic
but i can’t figure out that how will i distribute in the sets and then iterate on them and again when the knapasck is filled with at least one item of each set then again i need to iterate on all elements to get the remaining knapasack filled
@aryan_007,
You can ensure at least one by something like dp[i-1][j-wi] !=0.
Also, don’t mind complexity much at first, just code the correct recurrence even if it’s n^3, we will optimise afterwards.
okay i am able to take out at least one element from each set and grab the maxmium weight but now how to remove those elements to work on the remaining array like 0/1 knapsack.
@aryan_007,
You shouldn’t relax when dp[i-1][j-k] = 0, as then it means you are taking 0 element till i-1, which we cannot do as we have to take at least one of each color.
no sir , i didn’t relaxed there it is the reason i took vis map so that i know if it is taken only then i will have its contribution later and sir taking at least one element is working fine , the problem is how to take remaining elements . I mean i have taken at least 1 element from each set now next how to proceed.
@aryan_007,
I just wanted to ask why is there all 0’s in m=2 row of dp, doesn’t this means you haven’t picked up a single item of m=2 color?
Anyways, here is a implementation of this idea: Link.
no no that m=2 is actually m=0 , above 2 lines are the input not the dp table , dp table start from 000000000 line
it is kind of hard to follow through the code , can you please write some comments from here to here .
vector<vector> col(m);
for (int i = 1; i <= n; i++) {
col[c[i] - 1].push_back(w[i]);
}
vector<bool> dp(x + 2, false);
for (int j = 0; j <= (int)col[0].size() - 1; j++) dp[col[0][j]] = true;
for (int i = 1; i <= m - 1; i++) {
vector<bool> new_dp(x + 2, false);
for (int j = 0; j <= x; j++) {
if (dp[j]) {
for (int k = 0; k <= (int)col[i].size() - 1; k++) new_dp[min(x + 1, j + col[i][k])] = true;
}
}
dp = new_dp;
}
@aryan_007,
Both our codes are pretty much the same, col[c[i]] is same as your mp, basically accumulating all weights of same colour. Also even our dp is same. You can see in your dp, transition only depends on dp[i-1] and not any previous like dp[i-2], dp[i-3] etc. So it is just a space optimisation technique. We only keep last dp row, rather than the whole 2D table, and from that last row we calculate the new row, new_dp is basically the new calculated row of dp, which will replace the old one as we leave each loop.
And also in my code
if (dp[j]) { // if(dp[j] != 0)
ensures that I only take my answer from a column which is non-zero, which ensures that I take at least 1 for each color.
And my inner loop is same as yours
for (int j = 0; j <= x; j++) {
Just you have used range based and I have used a simple for loop.
okayyy sir , thankyou sir !!