Let dp_k[s] be the maximum value of cargo with a weight of at most , considering only the first types of items.
Now, consider two possible options when forming cargo of weight :
Do not use an item of type : In this case, the optimal value remains unchanged, meaning:
Use an item of type : Then its weight w_k will occupy part of the knapsack's capacity, and the value will increase by v_k, meaning:
Since the goal is to maximize the cargo value, we obtain the following recurrence relation:
Base cases:
Let the function f(k, s) compute the maximum value of cargo that can be packed into a knapsack with a weight limit of , using the first types of items. Then, the next recurrence relation holds:
Finally, we need to compute the value of f(k, s) using memoization.
Algorithm implementation
Declare the arrays:
— the weight of an item of type ;
— the value of an item of type ;
— the maximum value of cargo with a weight of at most ;
#define MAXW 252
#define MAXN 37
int w[MAXN], p[MAXN];
int dp[MAXW];Read the input data.
scanf("%d %d", &s, &n);
for (i = 0; i < n; i++)
scanf("%d %d", &w[i], &p[i]);Process types of items sequentially.
for (k = 0; k < n; k++)
{Update the values in the array, considering the possibility of using items of type . Since the number of items of each type is unlimited, each item can be chosen multiple times.
for (i = w[k]; i <= s; i++)
dp[i] = max(dp[i], dp[i - w[k]] + p[k]);
}Print the answer.
printf("%d\n", dp[s]);Algorithm implementation — recursion
Declare the arrays:
— the weight of an item of type ;
— the value of an item of type ;
— the maximum value of cargo with a weight of at most ;
#define MAXW 252
#define MAXN 37
#define INF 2000000000
int w[MAXN], v[MAXN];
int dp[MAXN][MAXW];The function f(k, s) computes the maximum value of cargo that can be packed into a knapsack with a weight limit of , using the first types of items.
int f(int k, int s)
{If k = 0 or s = 0, the knapsack is empty, and its value is .
if (k == 0 || s == 0) return 0;If s < 0, we have exceeded the allowed weight, making this option invalid. Therefore, we return (where is a sufficiently large number).
if (s < 0) return -INF;If the value of f(k, s) is already computed, return it.
if (dp[k][s] != -1) return dp[k][s];Compute f(k, s) and store it in dp[k][s].
return dp[k][s] = max(f(k - 1, s), f(k, s - w[k]) + v[k]);
}The main part of the program. Read the input data.
scanf("%d %d", &s, &n);
for (i = 1; i <= n; i++)
scanf("%d %d", &w[i], &v[i]);Compute and print the answer.
memset(dp, -1, sizeof(dp));
printf("%d\n", f(n, s));