public StolenItems FindKnackSnapMaxValueWithItems(int capacity, int[] weights, int[] values, int n) { //base case if (n == values.Length || capacity == 0) { StolenItems item = new StolenItems(); item.Max = 0; item.Items = string.Empty; return(item); } if (weights[n] > capacity) { //if the current n weight is greater than the capacity, skip n and go for next return(FindKnackSnapMaxValueWithItems(capacity, weights, values, n + 1)); } //Get the max value excluding the current for the weight of capacity StolenItems excludeitem = FindKnackSnapMaxValueWithItems(capacity, weights, values, n + 1); //Get the max value including the current for the weight of capacity //since we are includeitem = new StolenItems(); StolenItems includeitem = new StolenItems(); includeitem = FindKnackSnapMaxValueWithItems(capacity - weights[n], weights, values, n + 1); includeitem.Max = values[n] + includeitem.Max; StolenItems currentitem = new StolenItems(); //return the max of the including or excluding if (excludeitem.Max > includeitem.Max) { currentitem.Items = excludeitem.Items; currentitem.Max = excludeitem.Max; } else { currentitem.Items = includeitem.Items + " , " + values[n]; currentitem.Max = includeitem.Max; } return(currentitem); }
//Logic of this Dynamic Program //We iterate for each unit of the weight againt each item //As usual put the first row and column as zero (if there is no weight we can't put any item or if there is no item, there is no value) //If the item cannot be put into the bag of the weight(w), then put zero //if the item can fit into bag then take two values //value1 - one the cell about it cell[row -1, col] //and value2 - value of the item + (if there are any weight left, then find the left unit for this item and get the value from the row above row m[row -1, [weightleft] //set max of value1 and value2 //continue till last //last bottom right will be the answer and that is the maxvalue for using all weight and for all items //create an another array to keep track of all the matches- this will be used to backtrack the items //with the backtrack array you can check whether each item is added. It a item is added subtract it's weight and check the next item for the remaining weight //https://www.youtube.com/watch?v=EH6h7WA7sDw public StolenItems FindKnackSnapMaxValueWithItemsUsingDP(int[] weight, int[] values, int capacity) { //Declare an array with one index greater than given //Let's m the x-axia as weight and y axis as value int noofitems = weight.Length; int[,] maxarray = new int[noofitems + 1, capacity + 1]; int[,] backtrack = new int[noofitems + 1, capacity + 1]; // Build table K[][] in bottom up manner //noofitem = value.Length...not index //iterate for ech item for (int i = 0; i <= noofitems; i++) { //each unit of weight for (int j = 0; j <= capacity; j++) { if (i == 0 || j == 0) { maxarray[i, j] = 0; } //check the item can fit into the bag of capacity j //int[] weight is index based and we are iterating via length based else if (weight[i - 1] <= j) { //it can fit into the bag int value1 = maxarray[i - 1, j]; int value2 = values[i - 1] + maxarray[i - 1, (j - weight[i - 1])]; maxarray[i, j] = Math.Max(value1, value2); //logic for backtrack array.. //if the item is placed in the bag then mark 1 else 0 ( by default it is zero) if (maxarray[i, j] == value2) //which means this is placed in the bag { backtrack[i, j] = 1; } } else { //cannot fit maxarray[i, j] = 0; } } } StolenItems items = new StolenItems(); items.Max = maxarray[noofitems, capacity]; //We need to find the items //keep track of remaining capacity in the bag int w = capacity; bool[] itemsused = new bool[noofitems]; //check whether each item can be added from last item //i = 3,2,1 for (int i = noofitems; i > 0; i--) { if (backtrack[i, w] == 1) { //we are keeping this item in the bag itemsused[i - 1] = true; //substract actual weight of the item // w = w - 1; w = w - weight[i - 1]; } else { itemsused[i - 1] = false; } } StringBuilder sb = new StringBuilder(); for (int k = 0; k < itemsused.Length; k++) { if (itemsused[k]) { sb.Append(values[k]).Append(","); } } //test this logic use this logic in real world StringBuilder sb2 = new StringBuilder(); //values will be 0,1,2 int runningcapacity = capacity; for (int j = 0; j < values.Length; j++) { //backtrack array has one extra item so the corresponding value will be j + 1 if (backtrack[j + 1, runningcapacity] == 1) { sb2.Append(values[j]).Append(","); runningcapacity = runningcapacity - weight[j]; } } //check sb is equal to sb2 bool test = sb2.Equals(sb); items.Items = sb.ToString(); return(items); }