0-1背包问题有很多介绍,现在先不做说明,有时间补上。以下是递归的实现:
package test;
public class Package01 {
public int f(int n, int V,int[] w,int[] v)
{
if (n==0 || V==0)//当物品数量为0,或者背包容量为0时,最优解为0
{
return 0;
}
else
{
//如果当前要判断的物品重量大于背包当前所剩的容量,那么就不选择这个物品
//在这种情况的最优解为f(n-1,C)
if (w[n-1]>V) return f(n-1,V,w,v);
else
{
//如果当前待判断的物品重量wi
int tmp1 = f(n-1,V,w,v);//不选择物品i的情况下的最优解
int tmp2 = v[n-1] + f(n-1,V-w[n-1],w,v);//选择物品i的情况下的最优解
//返回选择物品i和不选择物品i中最优解大的一个
return tmp1 > tmp2?tmp1:tmp2;
}
}
}
public static void main(String args[])
{
int w[]={1,3,4,5};//物品重量数组
int v[]={2,30,44,20};//物品价值数组
Package01 pa=new Package01();
int maxvalue = pa.f(4,4,w,v);
System.out.println("Maximum Value is: "+maxvalue);
}
}
非递归的实现如下:
public static int package(int n,int V,int [] w,int [] v){
int [] f=new int[V+1];
for (int i=1;i<=n;i++){
for (int j=V;j>=w[i];j--){
f[j]=Math.max(f[j],f[j-w[i]]+v[i]);
}
}
return f[V];
}
非递归的过程如下:
测试数据:
10,3
3,4
4,5
5,6
先将f[] 全部初始化为0,其实也代表这个背包数组适应物品为空的时候所能容纳的最大物品价值。
下图中,黄色为当前正在操作的时候,黄色以上为上一次的数组状态,黄色以下可以不用看,那是以后的状态。
之后的思想是将物品不断添加进物品数组中,然后更新背包数组的所能容纳的最大物品价值。
添加第一个物品后:
。
。
。
添加完毕时是最后一行。
需要注意的是在更新背包所能容纳的最大物品价值时需要从后往前去更新,也就是下图的过程需要从W~w
因为按照背包问题的求解策略,大的背包容量所能容纳的最大物品价值是根据小 的背包容量所能容纳的最大物品价值计算出的,先更新大的背包容量的值不会影响之前的小的背包容量。
完全背包和0-1在非递归实现上相似,只是完全背包是使用正序的去更新数组,而0-1背包是逆序的去更新。
完全背包可以参考我的另一篇文章(自己的博客网站):http://amazingwu.xyz/2017/05/22/%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85/
最后本文参考了:http://blog.youkuaiyun.com/luojinping/article/details/6900788