0 - 1 背包问题介绍与 C# 代码实现

0 - 1 背包问题介绍

0 - 1 背包问题是一个经典的组合优化问题,属于 NP 完全问题。问题描述如下:

给定一组物品,每个物品有对应的重量 w[i] 和价值 v[i],以及一个容量为 C 的背包。要求在不超过背包容量的前提下,选择一些物品放入背包,使得背包中物品的总价值最大。这里的"0 - 1"表示对于每个物品,只能选择放入背包(1)或者不放入背包(0),不能只放入部分物品。

解决思路 - 动态规划

虽然贪心算法在某些情况下可以用于解决近似问题,但对于 0 - 1 背包问题,动态规划是一种能得到最优解的有效方法。动态规划的核心思想是将原问题分解为子问题,并保存子问题的解,避免重复计算。

设 dp[i][j] 表示前 i 个物品放入容量为 j 的背包中所能获得的最大价值。状态转移方程如下:

  • 当 j < w[i - 1] 时(即当前背包容量不足以放入第 i 个物品):dp[i][j] = dp[i - 1][j]
  • 当 j >= w[i - 1] 时(即当前背包容量可以放入第 i 个物品):dp[i][j] = Math.Max(dp[i - 1][j], dp[i - 1][j - w[i - 1]] + v[i - 1])

C# 代码实现

csharp 复制代码
using System;

class KnapsackProblem
{
    public static int Knapsack(int capacity, int[] weights, int[] values)
    {
        int n = weights.Length;
        int[,] dp = new int[n + 1, capacity + 1];

        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= capacity; j++)
            {
                if (weights[i - 1] > j)
                {
                    dp[i, j] = dp[i - 1, j];
                }
                else
                {
                    dp[i, j] = Math.Max(dp[i - 1, j], dp[i - 1, j - weights[i - 1]] + values[i - 1]);
                }
            }
        }

        return dp[n, capacity];
    }
}

class Program
{
    static void Main()
    {
        int[] weights = { 2, 3, 4, 5 };
        int[] values = { 3, 4, 5, 6 };
        int capacity = 8;

        int maxValue = KnapsackProblem.Knapsack(capacity, weights, values);
        Console.WriteLine("背包能装下的最大价值为: " + maxValue);
    }
}    

代码解释

  • Knapsack 方法接收背包容量 capacity、物品重量数组 weights 和物品价值数组 values 作为参数。
  • 使用二维数组 dp 来保存子问题的解。
  • 通过两层循环遍历所有物品和所有可能的背包容量,根据状态转移方程更新 dp 数组。
  • 最终返回 dp[n, capacity],即前 n 个物品放入容量为 capacity 的背包中所能获得的最大价值。

在 Main 方法中,定义了物品的重量、价值和背包容量,调用 Knapsack 方法计算并输出背包能装下的最大价值。

相关推荐
罗西的思考10 小时前
【轻量化复刻大模型 / KIMI K3】AttnRes 模块交互式演示
人工智能·算法·机器学习
SomeOtherTime11 小时前
Rust所有权(AI回答)
开发语言·后端·rust
Easyhood11 小时前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose
白杨尚青12 小时前
C++进阶篇(六):map 和 set 的模拟实现——用红黑树封装 mymap/myset(迭代器 + operator[])
开发语言·c++·迭代器·stl·set·map·红黑树
好悬给我拽开线14 小时前
ZILOT 论文解析
算法
饮水桶_T15 小时前
JAVA IO流笔记
开发语言·数据结构·算法
星夜离尘5616 小时前
MATLAB 离散数据分箱:半开区间、末端点与计数、加权和、平均
算法·matlab
Pniubi16 小时前
力扣76.最小覆盖子串
算法·leetcode·职场和发展
地平线开发者17 小时前
征程6|用 hrt\_model\_exec 看清 YOLOv5x 的输入、原始输出和后处理
人工智能·算法
csdn_aspnet17 小时前
C++ 3个有序点的方向(Orientation of 3 ordered points)
c++·算法