为何0-1背包递归DP代码仅取消注释printf行才正常运行?
Hey there, let's unpack this weird behavior you're seeing. The core issue here is undefined behavior from array out-of-bounds access, and that random printf is just accidentally masking the problem—let's break it down step by step.
1. The Critical Bug: Out-of-Bounds Array Initialization
Look at your dp array initialization loop:
static int dp[5][60]; // First dimension is 5 (valid indices 0-4) for (int i = 0; i <= 5; i++) { // i runs from 0 to 5 (inclusive) for (int w = 0; w <= 50; w++) { dp[i][w] = -1; } }
Your dp array only has 5 rows (indices 0 to 4), but your loop uses i <= 5, which means you're trying to write to dp[5][w]—this is an invalid out-of-bounds memory access. In C, this is undefined behavior: your program might crash, return wrong results, or even seem to work randomly depending on memory layout.
When you comment out the printf, this invalid write corrupts memory that's used elsewhere in your program (like valid entries in the dp array or stack variables), leading to incorrect results. When you leave the printf in, it just so happens to alter the memory state in a way that masks the corruption—this is pure coincidence, not a real fix.
2. Other Issues in Your Code
There are a few extra problems contributing to the instability:
- Invalid function declaration: You can't use
staticin function parameters like you did in the main function's declaration ofDP_Recursive. This isn't valid C syntax—remove thestatickeywords from the parameter list. - Missing
maxdefinition: The C standard library doesn't include a built-inmaxfunction. You'll need to define it yourself, e.g., add#define max(a, b) ((a) > (b) ? (a) : (b))at the top of your code. - Mismatched array sizes: Your
wtandvalarrays only hold 4 elements, but you declared them with size 5. While this doesn't break things immediately, it's messy and can lead to confusion later.
3. Fixed Version of Your Code
Here's how to fix the issues to make the code work reliably, with or without the printf:
#include <stdio.h> #define max(a, b) ((a) > (b) ? (a) : (b)) // Proper function declaration outside main int DP_Recursive(int W, int wt[], int val[], int n, int dp[5][60]); int main() { static int wt[4] = {5, 10, 20, 30}; // Corrected size to match elements static int val[4] = {50, 60, 100, 120}; static int dp[5][60]; // Marker array (rows 0-4 for n values 0-4) // Fixed loop: i runs only over valid dp rows (0-4) for (int i = 0; i < 5; i++) { for (int w = 0; w <= 50; w++) { dp[i][w] = -1; } } printf("The total loot is %d$.\n", DP_Recursive(50, wt, val, 4, dp)); // n=4 to include all items } // Recursive D.P. solution int DP_Recursive(int W, int wt[], int val[], int n, int dp[5][60]) { // Optional printf can be removed now without breaking functionality // printf("%d", dp[2][30]); // Base case if (n == 0 || W == 0) return 0; if (dp[n][W] != -1) return dp[n][W]; if (wt[n-1] > W) { dp[n][W] = DP_Recursive(W, wt, val, n - 1, dp); return dp[n][W]; } else { dp[n][W] = max(val[n-1] + DP_Recursive(W - wt[n-1], wt, val, n-1, dp), DP_Recursive(W, wt, val, n-1, dp)); } return dp[n][W]; }
Key Takeaways
- Out-of-bounds memory access is undefined behavior—never assume it will cause obvious crashes or consistent results. Always double-check array indices against their actual sizes.
- Random lines of code like the printf can sometimes mask undefined behavior by altering memory state, but this is never a real solution.
- Make sure your function declarations match their definitions and follow valid C syntax to avoid hidden issues.
内容的提问来源于stack exchange,提问作者Ravikant Sharma

