在算法学习中,动态规划(Dynamic Programming)是一个非常重要的思想,而背包问题则是动态规划中最经典、最常被提及的入门案例。本文将用通俗易懂的方式,带你一步步用 C#语言 实现 01背包问题 的求解过程,即使你是编程小白,也能轻松理解!
假设你有一个容量为 W 的背包,还有 n 个物品,每个物品都有自己的重量(weight)和价值(value)。你只能选择是否把某个物品放进背包(不能分割,即“0”或“1”),目标是在不超过背包容量的前提下,使背包中物品的总价值最大。
暴力枚举所有可能的组合虽然可行,但时间复杂度是 O(2^n),当物品数量稍大时就不可行了。而动态规划通过记忆化子问题,将时间复杂度优化到 O(n * W),效率大大提升。
我们使用一个二维数组 dp[i][w] 来表示:从前 i 个物品中选择,在背包容量为 w 时能获得的最大价值。
(n+1) x (W+1) 的二维数组,全部设为0。public static int Knapsack01(int[] weights, int[] values, int capacity){ int n = weights.Length; // 创建 dp 表,dp[i][w] 表示前 i 个物品在容量 w 下的最大价值 int[,] dp = new int[n + 1, capacity + 1]; // 填充 dp 表 for (int i = 1; i <= n; i++) { for (int w = 0; w <= capacity; w++) { // 如果当前物品太重,放不进去 if (weights[i - 1] > w) { dp[i, w] = dp[i - 1, w]; } else { // 取“放”与“不放”的最大值 dp[i, w] = Math.Max( dp[i - 1, w], // 不放 dp[i - 1, w - weights[i - 1]] + values[i - 1] // 放 ); } } } return dp[n, capacity];}
static void Main(string[] args){ int[] weights = { 2, 1, 3, 2 }; int[] values = { 12, 10, 20, 15 }; int capacity = 5; int maxValue = Knapsack01(weights, values, capacity); Console.WriteLine($"最大价值为: {maxValue}"); // 输出:37}
上述方法使用了 O(n * W) 的空间。其实我们只需要一维数组即可,因为每次只依赖上一行的数据。以下是空间优化版:
public static int Knapsack01Optimized(int[] weights, int[] values, int capacity){ int[] dp = new int[capacity + 1]; for (int i = 0; i < weights.Length; i++) { // 注意:必须从后往前遍历,避免重复使用同一物品 for (int w = capacity; w >= weights[i]; w--) { dp[w] = Math.Max(dp[w], dp[w - weights[i]] + values[i]); } } return dp[capacity];}
通过本教程,你已经掌握了如何用 C#动态规划 解决经典的 01背包问题。这不仅是面试高频题,也是理解动态规划思想的绝佳入口。记住核心思想:将大问题分解为子问题,并保存子问题的解避免重复计算。
希望这篇 C#算法教程 能帮助你打下坚实的算法基础。动手敲一遍代码,你会理解得更深刻!
关键词回顾:C#动态规划、背包问题、C#算法教程、01背包问题求解
本文由主机测评网于2025-12-25发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20251212606.html