0-1背包问题及动态规划求解

问题:

通过指定n个物品对应的重量w以及价值v,指定当前背包容量C,通过动态规划求解当前可以达到的最大价值以及如何装可以达到该最大价值。如:

C=23kg

商品序号

1

2

3

4

…..

重量

10kg

5kg

2kg

7kg

4kg

价值

80元

50元

10元

35元

24元

如何取得到最大价值?X[i]的取值?

③对上述算法进行时间复杂性分析,并输出程序运行时间及运行结果。

算法原理:

理解0/1背包问题的目标函数及约束函数。能够根据动态规划思想,进行0/1背包最优子结构性质分析、子结构递归关系构建、编码实现子结构最优值求解以及最优解构造。

解题思路:

首先定义一些变量:P表示物品的价值,W表示第 i 个物品重量,定义Pk:当前背包容量 j,前 i 个物品最佳组合对应的价值,同时背包问题抽象化(X1X2Xn,其中图中v操作表示选择,x操作表示不选)。步骤如下:1、建立模型,2、寻找约束条件,3寻找递推关系式,这步尤为关键,4填表找出最优解。下面我举个例子分析。

代码实现:

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<algorithm>

using namespace std;

int f[6][23]={0};

int w[6]={0,10,5,2,7,4};//第n件物品的重量

int v[6]={0,80,50,10,35,24};//第n件物品的价值

int main()

{  

    int i,j;

    memset(f,0,sizeof(f));

  for(int i=1;i<6;i++)

    for(int j=1;j<23;j++)

    {

      if(w[i]>j)

        f[i][j]=f[i-1][j];

      else

        f[i][j]=max(f[i-1][j-w[i]]+v[i],f[i-1][j]);

    }

    for (int i=0;i<6;i++)

    for(int j=0;j<9;j++)

        printf("f[%d][%d]=%d\n",i,j,f[i][j]);

}

其中关键部分是递归方程,其是算法的核心,分两种情况考虑,第一种是第k件物品不放在背包中的情况,第二种是当第k件物品的重量不大于背包剩余的容量时,意味着第k件物品可以放置在背包中,“可以放置”并不意味着一定要放在背包中吧,所以,存在两种情形,第k件物品放在背包中或者第k件物品不放在背包中。

实验记录: 

第一种情况

此时结果:

第二种情况:

结果如下

六、思考与总结

0-1背包问题是背包问题的延申,利用动态规划思想求解是比较快的,寻找递归关系,通过填表方式把子问题记录下了,最后找到最优解。在0-1背包问题中关键就是寻找递归方程,摸清他们的关系。这里我就分两种情况来看,第一种是第k件物品不放在背包中的情况,第二种是当第k件物品的重量不大于背包剩余的容量时,意味着第k件物品可以放置在背包中,“可以放置”并不意味着一定要放在背包中吧,所以,存在两种情形,第k件物品放在背包中或者第k件物品不放在背包中。搞清楚这点问题就简单了,最后使用回溯,轻松输出。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值