最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
01背包问题c语言代码穷举怎么写
时间:2026-09-09 19:02:51 编辑:袖梨 来源:一聚教程网
在前端开发内容学习中,01背包问题c语言代码穷举怎么写?完整思路与示例是常见主题。很多人在阅读时会遇到概念分散、步骤不清和注意点难以归纳的问题。本文按照基础概念、操作流程和关键细节,对相关内容进行整理。

01背包问题c语言代码穷举适合用来理解选择与不选择两种分支的搜索过程。本文用清晰的状态定义、完整代码和小样例说明如何从输入、递归到结果输出一步步写对。
先明确01背包穷举在枚举什么
01背包问题的核心是:每件物品只有取与不取两种状态,在总容量不超过限制的前提下,让总价值尽量大。穷举写法不是直接猜答案,而是把每件物品的两种选择都走一遍,再比较最后结果。
用C语言实现时,最重要的是先把状态说清楚。常见状态包括当前处理到第几件物品、已经用了多少容量、当前累计价值是多少。只要这三个量定义稳定,递归过程就不会写乱。
穷举代码的价值不在速度,而在思路直观。它能帮助你看懂01背包为什么能拆成分支搜索,也方便后面再过渡到动态规划版本。这里需要注意,这种写法本质上会枚举每件物品“选”或“不选”的全部情况,时间复杂度通常是O(2^n)。当物品数量很少时,它比较适合学习、调试和验证;但当n变大后,搜索规模会迅速膨胀,这时更适合切换到动态规划等更高效的解法。
- 每到一件物品,都有“不选它”和“选它”两条分支。
- 只有在加入当前物品后容量不超限时,才允许进入“选它”的分支。
- 当所有物品都处理完时,用当前价值更新全局最优解。
- 穷举更适合小规模数据或学习搜索过程,不适合物品数量很大的输入。
递归函数应该怎样设计
写穷举时,建议把递归函数参数控制在最必要的范围内。最常见的做法是传入当前下标index、当前重量curWeight、当前价值curValue,这样每次递归只需要关心下一件物品如何处理。
递归出口通常是index等于物品总数,也就是所有物品都已经决定完毕。到了这个位置,就比较curValue和当前记录的最大价值maxValue,如果更大就更新答案。
为了避免逻辑重复,先无条件走“不选当前物品”的分支,再判断是否还能放下当前物品;如果能放下,再走“选当前物品”的分支。这个顺序简单,调试时也更容易跟踪。
递归设计要点
- 参数要能完整描述当前搜索状态,常用的是下标、已用容量、当前价值。
- 出口条件只负责更新最优值,不要在出口里再做多余判断。
- 容量判断放在进入“选择分支”之前,避免出现非法状态。
01背包问题c语言代码穷举完整示例
下面这份代码使用固定数组演示最基础的穷举写法。程序会遍历每件物品的选与不选,最后输出最大总价值,适合先跑通思路,再根据需要扩展成从键盘输入数据的版本。
示例中共有4件物品,重量分别为2、1、3、2,价值分别为12、10、20、15,背包容量为5。这个样例的实际最优组合是选择第1、2、4件物品,总重量2+1+2=5,总价值12+10+15=37;而像第1、3件物品的组合虽然总重量也是5,但总价值只有32,所以不是最优解。这样就能先在纸面上验算出正确答案,再对照程序输出。
完整示例
#include <stdio.h> #define N 4 int weights[N] = {2, 1, 3, 2}; int values[N] = {12, 10, 20, 15}; int capacity = 5; int maxValue = 0; void dfs(int index, int curWeight, int curValue) { if (index == N) { if (curValue > maxValue) { maxValue = curValue; } return; } dfs(index + 1, curWeight, curValue); if (curWeight + weights[index] <= capacity) { dfs(index + 1, curWeight + weights[index], curValue + values[index]); } } int main(void) { dfs(0, 0, 0); printf("最大价值:%dn", maxValue); return 0; }- 编译命令:
cc -std=c11 knapsack.c -o knapsack - 运行命令:
./knapsack 运行输出
最大价值:37
如何检查结果是否写对
穷举代码最容易出错的地方,不是语法,而是边界。比如下标是否越界、容量判断是否漏掉、最大值是否在正确位置更新,这些问题都会让结果偏小或直接出错。
一个实用办法是先用很小的数据做人工验算。像4件物品这样的样例,总共有16种选择情况,虽然程序自动搜索,但你可以手工列几种关键组合,对照程序输出是否一致。
以本文样例来说,第1、3件物品的组合重量是5、总价值是32;第2、3件物品的组合重量是4、总价值是30;第1、2、4件物品的组合重量是5、总价值是37。对比后可以确认,37确实大于这些关键组合的价值,所以程序输出“最大价值:37”是合理的。
如果你后面准备改成动态规划,也建议先把穷举版写对。因为穷举版能帮你确认题意、变量含义和最优值基准,后续优化时不容易把状态转移写偏。动态规划的优势在于能复用子问题结果,常见写法时间复杂度通常比纯穷举更可控,更适合处理中大规模输入。
- 先测容量很小、物品数量很少的样例,便于人工核对。
- 若输出始终为0,优先检查递归出口和maxValue更新位置。
- 若结果偏小,重点检查“选择分支”前的容量判断是否写错。
- 若程序崩溃,检查数组下标和递归终止条件是否正确。
常见扩展怎么改
很多人搜索01背包问题c语言代码穷举怎么写,不只是想看固定数组版本,还想知道实际项目或练习里怎么扩展。最常见的两个方向,就是把样例改成键盘输入,以及在求出最大价值后顺便输出选择了哪些物品。
如果要改成键盘输入,可以先读入物品数量n和背包容量capacity,再循环输入每件物品的重量与价值,分别存到数组里。这样程序就不再依赖写死的测试数据,更适合做OJ练习或课堂作业。
如果要输出选择了哪些物品,做法通常是在递归过程中额外记录当前路径,并在发现更优解时,把当前路径保存为最佳方案。这样最终不仅能输出最大价值,还能输出被选中的物品编号,形成“题目-代码-结果验证”的完整闭环。
常见扩展方向
- 把固定数组改成scanf读入n、capacity、weights和values,更贴近真实输入场景。
- 在递归中增加路径记录数组,更新最优值时同步保存最佳选择方案。
- 如果数据规模明显变大,优先考虑动态规划,不要继续沿用纯穷举。
如果你是刚接触01背包问题,先把这类C语言穷举代码写通,比直接背动态规划公式更有效。等你能清楚说明状态、分支、出口,以及样例为什么得到37这个最优值,再去做优化版本会更稳。
相关文章
- 机甲对抗战最强阵容一览表讲了什么-主要信息和内容重点 09-09
- c语言函数递归调用简单例子看懂终止条件和返回过程 09-09
- tlwdr6500路由器怎么无线桥接(tlwdr6500路由器无线桥接方法) 09-09
- c语言详细基础教程|从语法到上机入门 09-09
- [c语言教程pdf]入门到进阶学习要点 09-09
- 异环爱丽丝烘培坊完成攻略 异环爱丽丝烘培坊怎么完成怎么做-剧情梗概和任务条件 09-09