0-1背包问题递归与非递归实现

本文介绍了0-1背包问题,包括递归和非递归两种实现方式,旨在帮助读者理解动态规划在解决背包问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值