Problem Statement
Given a set of items, each with a weight and a value, you need to find the maximum value you can carry in a knapsack of a fixed capacity.
Key Concepts
- Dynamic Programming: This method breaks down the problem into simpler subproblems and builds up solutions to larger problems based on the solutions to smaller ones.
- State Representation: We use a 2D array
dp
wheredp[i][w]
represents the maximum value that can be attained with a maximum weightw
using the firsti
items.
Dynamic Programming Approach
- Step 1: Initialize a 2D array
dp
where the rows represent items and the columns represent weights from0
to the maximum capacity. - Step 2: Iterate over each item and each weight to fill the
dp
table based on whether to include or exclude the item. - Step 3: The maximum value will be found in
dp[n][W]
, wheren
is the number of items andW
is the maximum capacity.
C Program for 0/1 Knapsack Problem
#include <stdio.h>
#include <stdlib.h>
// Function to solve the 0/1 Knapsack Problem
int knapsack(int W, int weights[], int values[], int n) {
int** dp = (int**)malloc((n + 1) * sizeof(int*));
for (int i = 0; i <= n; i++) {
dp[i] = (int*)malloc((W + 1) * sizeof(int));
}
// Build the dp table
for (int i = 0; i <= n; i++) {
for (int w = 0; w <= W; w++) {
if (i == 0 || w == 0) {
dp[i][w] = 0; // Base case
} else if (weights[i - 1] <= w) {
// Max of including the item or not
dp[i][w] = (values[i - 1] + dp[i - 1][w - weights[i - 1]] > dp[i - 1][w]) ?
values[i - 1] + dp[i - 1][w - weights[i - 1]] : dp[i - 1][w];
} else {
dp[i][w] = dp[i - 1][w]; // Cannot include the item
}
}
}
// Get the maximum value from the last cell
int maxValue = dp[n][W];
// Free the allocated memory
for (int i = 0; i <= n; i++) {
free(dp[i]);
}
free(dp);
return maxValue;
}
// Main function
int main() {
int n, W;
// Input the number of items
printf("Enter the number of items: ");
scanf("%d", &n);
int* weights = (int*)malloc(n * sizeof(int));
int* values = (int*)malloc(n * sizeof(int));
// Input the weights and values
printf("Enter the weights of the items: ");
for (int i = 0; i < n; i++) {
scanf("%d", &weights[i]);
}
printf("Enter the values of the items: ");
for (int i = 0; i < n; i++) {
scanf("%d", &values[i]);
}
// Input the maximum capacity of the knapsack
printf("Enter the maximum capacity of the knapsack: ");
scanf("%d", &W);
// Calculate the maximum value that can be carried
int maxValue = knapsack(W, weights, values, n);
printf("Maximum value in the knapsack: %d\n", maxValue);
// Free the allocated memory
free(weights);
free(values);
return 0;
}
Explanation of the Code
- Dynamic Programming Table:
- We create a 2D array
dp
wheredp[i][w]
stores the maximum value for the firsti
items and a maximum weight ofw
.
- We create a 2D array
- Filling the DP Table:
- We iterate through the items and weights. For each item, we check if we can include it in the knapsack. If the current item’s weight is less than or equal to the current weight
w
, we have the option to include it or not. If we exclude it, we take the value from the previous item.
- We iterate through the items and weights. For each item, we check if we can include it in the knapsack. If the current item’s weight is less than or equal to the current weight
- Maximum Value Extraction:
- After populating the
dp
array, the maximum value that can be carried is found atdp[n][W]
.
- After populating the
- Memory Management:
- The program dynamically allocates memory for the weights, values, and
dp
table, and frees that memory at the end to prevent memory leaks.
- The program dynamically allocates memory for the weights, values, and
Input and Output Example
Input
mathematicaCopy codeEnter the number of items: 4
Enter the weights of the items: 1 2 3 2
Enter the values of the items: 20 5 10 40
Enter the maximum capacity of the knapsack: 5
Output
yamlCopy codeMaximum value in the knapsack: 60
Explanation of the Output
In this example, the maximum value of 60
can be achieved by including items with weights 2
and 3
, which have values 40
and 20
respectively.
Conclusion
This C program effectively solves the 0/1 Knapsack Problem using dynamic programming. It allows for user input for flexibility and computes the maximum value that can be placed in the knapsack given specific weights and values. You can test different sets of items and capacities to see how the optimal solution changes. This approach is widely applicable in resource allocation problems.