[算法]01背包问题

6 篇文章 0 订阅

子问题的最优解也是全局最优解

对于一个物品, 选择放还是不放,只有两个选择, 故属于01问题.

// 物品;
public class Item
{
    // 重量;
    public int Weight;
    // 价值;
    public int Value;
    // 是否放入;
    public bool Input;
}

核心算法

// 第n件物品,放入剩余容量为leftWeight的背包中所获得的最大价值;
        static int GetMaxValue(List<Item> list, int n, int leftWeight)
        {
            // 对n进行边界判断;
            // 最后一个物品,还是要计算的故<0;
            if (n < 0 || n >= list.Count)
            {
                return 0;
            }

            // 如果当前n的容量超过背包的剩余容量则不放入;
            if (list[n].Weight > leftWeight)
            {
                // 不能放入;
                // 当前n的最大价值为n-1的最大价值;
                return  GetMaxValue(list, n - 1, leftWeight);
            }
            else
            {
                // 能放入,判断是放入还是不放入;

                // 不放入的最大价值;  
                int maxValue_n_1 = GetMaxValue(list, n - 1, leftWeight);
                // 放入的最大价值;
                int maxValue_n = GetMaxValue(list, n - 1, leftWeight - list[n].Weight) + list[n].Value;

                // 比较当前放入的和不放入的最大价值的大小;
                list[n].Input = maxValue_n_1 > maxValue_n ? false : true;
                return maxValue_n_1 > maxValue_n ? maxValue_n_1 : maxValue_n;
            }

        }

测试

using System;
using System.Collections.Generic;

namespace _01Bag
{
    class Program
    {
        // 物品;
        public class Item
        {
            // 重量;
            public int Weight;
            // 价值;
            public int Value;
            // 是否放入;
            public bool Input;
        }

        // 第n件物品,放入剩余容量为leftWeight的背包中所获得的最大价值;
        static int GetMaxValue(List<Item> list, int n, int leftWeight)
        {
            // 对n进行边界判断;
            // 最后一个物品,还是要计算的故<0;
            if (n < 0 || n >= list.Count)
            {
                return 0;
            }

            // 如果当前n的容量超过背包的剩余容量则不放入;
            if (list[n].Weight > leftWeight)
            {
                // 不能放入;
                // 当前n的最大价值为n-1的最大价值;
                return  GetMaxValue(list, n - 1, leftWeight);
            }
            else
            {
                // 能放入,判断是放入还是不放入;

                // 不放入的最大价值;  
                int maxValue_n_1 = GetMaxValue(list, n - 1, leftWeight);
                // 放入的最大价值;
                int maxValue_n = GetMaxValue(list, n - 1, leftWeight - list[n].Weight) + list[n].Value;

                // 比较当前放入的和不放入的最大价值的大小;
                list[n].Input = maxValue_n_1 > maxValue_n ? false : true;
                return maxValue_n_1 > maxValue_n ? maxValue_n_1 : maxValue_n;
            }

        }

        static void Main(string[] args)
        {
            // 背包的最大容量;
            int MaxWeight = 10;
            // 物品列表;
            List<Item> itemList = new List<Item>();
            Item oneItem = null;

            oneItem = new Item();
            oneItem.Weight = 2;
            oneItem.Value = 6;
            itemList.Add(oneItem);

            oneItem = new Item();
            oneItem.Weight = 2;
            oneItem.Value = 3;
            itemList.Add(oneItem);

            oneItem = new Item();
            oneItem.Weight = 6;
            oneItem.Value = 5;
            itemList.Add(oneItem);

            oneItem = new Item();
            oneItem.Weight = 5;
            oneItem.Value = 4;
            itemList.Add(oneItem);
            oneItem = new Item();
            oneItem.Weight = 4;
            oneItem.Value = 6;
            itemList.Add(oneItem);

            // 最大价值;
            int maxValue = GetMaxValue(itemList, itemList.Count - 1, MaxWeight);
            Console.WriteLine("maxValue: " + maxValue);
            for (int i = 0; i < itemList.Count; ++i)
            {
                Console.WriteLine(i + " =>" + itemList[i].Input);
            }
            Console.ReadLine();
        }


    }
}

测试结果

测试结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值