动态规划之01背包问题

01背包问题描述:

有N(N>=1)个物品,具有不同的重量和价值,另有一个容量为V的背包,求在重量不超过V的情况下,使得所装物品的价值最大。

思路

  1. 首先找到动态规划中的状态,即f[i,j],i代表允许i个物品放入到背包中,j代表背包的容积,f[i,j]表示当允许i个物品放入到容积为j的背包中的时候的最大总价值。为什么这里说i代表的是允许i个物品可放入背包中呢?意思是,现在可供挑选的物品有i个,每个物品都可放或不放入背包中。
  2. 接下来找到状态转移方程,当我们只有一个物品可供选择时,当weight[1]>j(第一个物品的重量大于背包的容量)时,f[1,j] = 0;若weight[1]<=j时,我们就可以把第一个物品放入背包,且背包的总价值为value[1],随着背包容量j的增大,背包的价值不改变(因为只有一个物品可供选择)
  3. 当有两个物品可供选择时,若背包的j小于weight[i](1<=i<=2),背包的价值为0,当j>=weight[2]时,需比较当背包容量为j时,i=1时背包总价值f[1][j](即不放第二个物品的价值)与放第二个物品价值f[1,j-weight[i]]+value[i](表示在放第二个物品之前,我们要先知道背包除去留下用来装第二个物品的容量后剩余的容量用来装第一个物品的最大价值,然后用这个值加上第二个物品的价值),即取f[i-1,j]和f[i-1,j-weight[i]]+value[i] 的最大值,状态转移方程f[i][j] = max{f[i-1,j],f[i-1,j-weight[i]]+value[i] }
  4. 举个例子说明,物品的重量int[] weight = {2,2,6,5,4} 对应的价值int[] value = {6,3,5,4,6},背包的容积10,具体数据看下图
    这里写图片描述
    附上C#代码
C#代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BubbleSort
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] value = {0,6,3,5,4,6};
            int[] weight = {0,2,2,6,5,4};
            BagQ(value,weight,10);
        }

        #region 动态规划之背包问题
        private static void BagQ(int[] value, int[] weight,int maxV)
        {
            int[,] re = new int[weight.Length,maxV+1];
            re[0, 0] = 0;
            for (int i = 1; i < weight.Length; i++)
            {
                for (int j = 0; j <= maxV; j++)
                {
                    if (j >= weight[i] && re[i - 1, j - weight[i]] + value[i] > re[i - 1, j])
                    {
                        re[i, j] = re[i - 1, j - weight[i]] + value[i];
                    }
                    else
                    {
                        re[i, j] = re[i - 1, j];
                    }
                }

            }

            Console.WriteLine("01背包问题的最优解:"+re[weight.Length-1,maxV]);
            Console.ReadLine();
        }
        #endregion

     }  
}

运行结果就不贴了,有看到其它博主的博文,提到上表要从下至上,从左到右生成,我是从上到下,从左到右做的,若有错误,请指正

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值