You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现0-1背包算法遇问题:数组越界或结果为0

解决你的0-1背包算法问题:数组越界与结果异常

我帮你拆解下代码里的核心问题,以及对应的修复方案:

问题1:数组索引越界的根源

你的代码里,k从0循环到n(也就是物品总数3),但当k >= 1时直接用k访问s[k]和v[k]是错误的——C#数组是0基索引,s和v的有效索引范围是0到2(对应3个物品)。当k=3时,s[3]就会触发"Index was outside the bounds of the array"错误。

正确的做法是:当处理第k个物品(从1开始计数)时,用k-1去访问数组里的对应元素。

问题2:循环范围错误导致结果未更新

你的内层循环条件是for (int r = 0; r < w; r++),这意味着你只计算了背包容量从0到w-1的情况,而最后返回的G[n, w](容量为w的场景)从来没被赋值过,一直是默认的0。需要把循环条件改成r <= w,才能覆盖到目标容量的计算。

额外说明:当前测试用例的特殊性

你现在的测试用例里,所有物品的重量(60、100、120)都大于背包容量50,所以即使代码修复了,返回结果还是0——这是正确的,因为确实装不下任何物品。可以换个测试用例验证,比如把背包容量改成100,就能看到正确的计算结果。

修正后的完整代码

static int Knapsack(int n, int w, int[] s, int[] v) 
{
    int[,] G = new int[n+1, w+1]; 
    
    for (int k = 0; k <= n; k++) 
    {
        // 修正循环条件:覆盖到容量为w的情况
        for (int r = 0; r <= w; r++) 
        {
            if (r == 0 || k == 0) 
                G[k, r] = 0;
            // 修正数组索引:用k-1访问物品的重量和价值
            else if (s[k-1] <= r) 
                G[k, r] = Math.Max(G[k-1, r], v[k-1] + G[k-1, r - s[k-1]]);
            else 
                G[k, r] = G[k-1, r];
        }
    }
    return G[n, w]; 
}

static void Main(string[] args) 
{
    int[] s = { 60, 100, 120}; 
    int[] v = { 10, 20, 30 }; 
    int w = 100; // 改成能装下物品的容量,验证计算结果
    int n = s.Length; 
    Console.WriteLine(Knapsack(n, w, s, v)); // 此时会返回20,对应选择重量100、价值20的物品
}

验证修改效果

  • 修正后不会再触发数组越界错误;
  • 当背包容量设置为160时,代码会返回30(选择重量60+100的物品,总价值10+20=30,和第三个物品价值一致);
  • 完全符合0-1背包的动态规划逻辑。

内容的提问来源于stack exchange,提问作者Ekli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:12:51