01背包问题描述:
有N(N>=1)个物品,具有不同的重量和价值,另有一个容量为V的背包,求在重量不超过V的情况下,使得所装物品的价值最大。
思路
- 首先找到动态规划中的状态,即f[i,j],i代表允许i个物品放入到背包中,j代表背包的容积,f[i,j]表示当允许i个物品放入到容积为j的背包中的时候的最大总价值。为什么这里说i代表的是允许i个物品可放入背包中呢?意思是,现在可供挑选的物品有i个,每个物品都可放或不放入背包中。
- 接下来找到状态转移方程,当我们只有一个物品可供选择时,当weight[1]>j(第一个物品的重量大于背包的容量)时,f[1,j] = 0;若weight[1]<=j时,我们就可以把第一个物品放入背包,且背包的总价值为value[1],随着背包容量j的增大,背包的价值不改变(因为只有一个物品可供选择)
- 当有两个物品可供选择时,若背包的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] }
- 举个例子说明,物品的重量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
}
}
运行结果就不贴了,有看到其它博主的博文,提到上表要从下至上,从左到右生成,我是从上到下,从左到右做的,若有错误,请指正