背包问题解析

     今天看到算法:C语言实现这本书 第五章递归与树 中 背包问题,想到对这个问题理解不够透彻. 希望利用第一篇技术博客好好的吃透它.

     背包问题是什么?

     设有i类不同大小和价值的物品,背包的可用容积为cap,进行合理的物品选择使得所装入的物品价值最大.

      背包问题解法?

      设定:背包大小为cap,对应第i项物品记为item[i],

      定义结构体:

      typedef struct

  {   int size;

         int val; 

      }item;

      思路:利用递归解法,每次我们选择一个项,我们都假设可以递归的找到打包剩余背包的最优方式. 对于大小为cap的背包,对于可用类型中任何一项i,我们可以把i放入背包的同时,使得其他项有最优打包,来得到一种最优解.简单地说最优打包的方式就是已经找到(或将要找到)大小为capp-item[i].size的更小背包.这种解法利用了最优决策原理.

     递归实现 大量的重复计算

     int knap(int cap)

     {  int i,space,max,t;

        for(i=0,max=0;i<N;i++)

            if((space = cap - items[i].size)>=0)

                if((t = knap(space) + items[i].val) > max)

                      max = t;

        return max;

      } 

      代码分析:蓝色标记的是程序的关键,对于背包问题,进行如上所说思路递归,对于空间和时间的双重把控是关键。递归遍历每一种存在的可能,再一次和max比较,众所周知 会有大量重复的出现,一般程序设计中不考虑。

     动态规划实现  递归升级版 检索已保存的值 使用一个观察哨来表达未知值而不是进行递归调用.

      int knap(int M)

      {int i,space,max,maxi,t;

        if(maxknown[M] != unknown) return maxknown[M];

        for(i=0,max=0;i<N;i++)

            if((t = knap(space) + items[i].val) > max)

                 { max = t ; maxi = i;}

        maxKnown[M] = max; itemKnown[M] = items[maxi];

        return max;

      }

       代码分析:存储项的索引,以便能够在计算之后重建背包的内容,如果希望itemKnown[M]在背包中,那么余下的内容就跟大小为M-itemKnown[M].size的最优背包内容一致,因此,itemKnown[M-item[M].szie]在背包里,以此类推。

      动态规划继续思考中...

     

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值