📖 Scenario: Imagine you are helping a small delivery company decide the best way to pack their trucks with packages. Each package has a weight and a value. The company wants to maximize the total value of packages in the truck without exceeding the weight limit.There are three ways to solve this problem: simple recursion, dynamic programming, and a greedy approach. You will learn how to set up the data, configure the problem, apply each method, and see the results.
🎯 Goal: Build a program that uses recursion, dynamic programming, and greedy methods to solve the package packing problem. You will compare their outputs to understand which method works best for this problem.
📋 What You'll Learn
Create an array of package weights and values
Set a maximum weight limit for the truck
Implement a recursive function to find max value
Implement a dynamic programming solution for max value
Implement a greedy approach based on value-to-weight ratio
Print the results of all three methods
💡 Why This Matters
🌍 Real World
Delivery companies and logistics use these methods to pack trucks efficiently, saving fuel and time.
💼 Career
Understanding these approaches helps in roles like software engineering, data analysis, and operations research where optimization problems are common.
Progress0 / 4 steps
1
Create package data arrays
Create two arrays called weights and values with these exact values: weights = {2, 3, 4, 5} and values = {3, 4, 5, 6}. Also create an integer n set to 4 representing the number of packages.
DSA C
Hint
Use array syntax to create weights and values. Set n to 4.
2
Set the maximum weight limit
Create an integer variable called maxWeight and set it to 5 to represent the truck's weight limit.
DSA C
Hint
Declare int maxWeight = 5; inside main.
3
Implement recursive solution
Write a recursive function called knapsackRecursive that takes three parameters: int i (current index), int w (current weight), and returns the maximum value that can be obtained without exceeding maxWeight. Use the arrays weights and values and the variable n. Then call this function from main with i = 0 and w = 0 and store the result in int resultRec.
DSA C
Hint
Use recursion to try including or excluding the current package. Return the max value.
4
Print the recursive result
Add a printf statement in main to print the text "Recursive result: " followed by the value of resultRec.
DSA C
Hint
Use printf("Recursive result: %d\n", resultRec); to print.
Practice
(1/5)
1. Which approach is best suited when a problem has overlapping subproblems and optimal substructure?
easy
A. Dynamic Programming
B. Greedy Algorithm
C. Simple Recursion without memoization
D. Brute Force
Solution
Step 1: Understand problem characteristics
Overlapping subproblems mean the same smaller problems repeat. Optimal substructure means the best solution can be built from best solutions of smaller problems.
Step 2: Match approach to characteristics
Dynamic Programming stores results of subproblems to avoid repeated work, ideal for overlapping subproblems and optimal substructure.
Hint: Use DP when subproblems repeat and build optimal solutions [OK]
Common Mistakes:
Choosing greedy when subproblems overlap
Using simple recursion without memoization causing slow code
Confusing optimal substructure with greedy choice property
2. Which of the following is the correct syntax to implement memoization in C for a recursive Fibonacci function?
easy
A. Use a global array to store results and check before recursive calls
B. Use a local variable inside the function to store results
C. Use a static variable without initialization inside the function
D. Use a pointer without allocating memory for memoization
Solution
Step 1: Understand memoization storage
Memoization requires storing results outside the recursive calls to reuse them. A global or static array is suitable.
Step 2: Check options for correct usage
Only a global array checked before recursion ensures stored results are reused properly. Local variables reset each call, static without init may cause errors, pointers need allocation.
Final Answer:
Use a global array to store results and check before recursive calls -> Option A
Quick Check:
Memoization needs persistent storage = global array [OK]
Hint: Memoize with global/static array checked before recursion [OK]
Common Mistakes:
Using local variables that reset each call
Not initializing static variables properly
Using pointers without memory allocation
3. What will be the output of the following C code snippet implementing a greedy approach for coin change?
int coins[] = {25, 10, 5, 1};
int amount = 30;
int count = 0;
for (int i = 0; i < 4; i++) {
while (amount >= coins[i]) {
amount -= coins[i];
count++;
}
}
printf("%d\n", count);
medium
A. 3
B. 2
C. 4
D. 5
Solution
Step 1: Trace the greedy coin selection
Start with 30 amount. Use 25 coin once (30-25=5), count=1. Then 10 coin can't be used (5<10). Use 5 coin once (5-5=0), count=2.
Step 2: Count total coins used
Coins used: 25 (1), 5 (1), total count = 2 coins. The code increments count inside while loop, so count=2.
Step 3: Check for remaining coins
Amount is now 0, so no more coins used.
Final Answer:
2 -> Option B
Quick Check:
Greedy coin count for 30 = 2 coins [OK]
Hint: Subtract largest coin repeatedly until amount zero [OK]
Common Mistakes:
Counting coins incorrectly by missing loops
Assuming greedy always gives minimum coins
Confusing coin values and counts
4. Identify the error in this recursive function for factorial and suggest the fix:
int factorial(int n) {
if (n == 0) return 0;
return n * factorial(n - 1);
}
medium
A. Recursive call should be factorial(n + 1)
B. Function should return void
C. Base case should return 1 instead of 0
D. No error, code is correct
Solution
Step 1: Analyze base case correctness
Factorial of 0 is 1, but code returns 0, which will cause all results to be zero.
Step 2: Suggest correct base case
Change base case to return 1 when n == 0 to correctly end recursion and compute factorial.
Final Answer:
Base case should return 1 instead of 0 -> Option C
Quick Check:
Factorial(0) = 1 base case [OK]
Hint: Factorial base case returns 1, not 0 [OK]
Common Mistakes:
Returning 0 in base case causing zero product
Changing recursion direction incorrectly
Ignoring base case leading to infinite recursion
5. You want to find the minimum number of coins to make a given amount using coins of denominations {1, 3, 4}. Which approach is best and why?
hard
A. Brute force, to try all combinations without optimization
B. Recursion without memoization, to explore all possibilities
C. Greedy, because always picking largest coin works
D. Dynamic Programming, to store and reuse subproblem results
Solution
Step 1: Understand problem requirements
Minimum coins for amount with coins {1,3,4} needs checking all combinations to find optimal solution.
Step 2: Evaluate approaches
Greedy fails here because picking largest coin first may not yield minimum coins. Recursion without memoization is slow. Dynamic Programming stores results of smaller amounts to build optimal solution efficiently.
Final Answer:
Dynamic Programming, to store and reuse subproblem results -> Option D
Quick Check:
Minimum coins with overlapping subproblems = DP [OK]
Hint: Use DP when greedy fails to find minimum coins [OK]
Common Mistakes:
Assuming greedy always works for coin change
Using recursion without memo causing slow code
Ignoring overlapping subproblems in coin change
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.