首页 > 其他 > 详细

混合背包

时间:2017-02-04 18:50:18      阅读:103      评论:0      收藏:0      [点我收藏+]

问题    

如果将01背包、完全背包、多重背包混合起来。应该怎么求解呢?

01背包与完全背包的混合   

考虑到在01背包和完全背包中最后给出的伪代码只有一处不同,故如果只有两类物品:一类物品只能取一次,另一类物品可以取无限次,那么只需在对每个物品应用转移方程时,根据物品的类别选用顺序或逆序的循环即可,复杂度是O(VN)。

伪代码如下:

for i=1..N  

if 第i件物品是01背包   

for v=V..0   

f[v]=max{f[v],f[v-w[i]]+c[i]};  

else if 第i件物品是完全背包   

for v=0..V    

f[v]=max{f[v],f[v-w[i]]+c[i]};

再加上多重背包   

转二进制优化的01背包就好了。还有一种神奇的东西叫单调队列优化,然而我也不会,有兴趣可以自学一下。

混合三种背包问题                       

有一个旅行者有一个最多能装v公斤的背包,现有n件物品,他们的重量分别是w1,w2,w3...他们的价值分别是c1,c2..

有的物品只可以取一次,有的物品只可以取无限次,有的物品有上限,求价值最大和。

输入   背包容量m<=200,物品数量n<=30

       从第二行每行三个整数 w,c,p;物重,价值,数量

       P==0说明能取无数件

输出  最大值

样例  输入             输出

10 3               11

2  1  0

3  3  1

4  5  4

参考程序

     #include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

using namespace std;

int n,m;

int c[40],w[40],p[40];

int f[201];

int main()

{

scanf("%d%d",&m,&n);

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

   scanf("%d%d%d",&w[i],&c[i],&p[i]);

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

   if(p[i]==0)

     for(int j=w[i];j<=m;j++)

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

   else

      for(int j=1;j<=p[i];j++)

         for(int k=m;k>=w[i];k--)

           f[k]=max(f[k],f[k-w[i]]+c[i]);

printf("%d",f[m]);

return 0;

}

 

4:题目描述

    背包体积为V ,给出N个物品,每个物品占用体积为Vi,价值为Wi,每个物品要么至多取1件,要么至多取mi件(mi > 1, 要么数量无限 , 在所装物品总体积不超过V的前提下所装物品的价值的和的最大值是多少?

 输入描述

第一行两个数N,V,下面N行每行三个数Vi,Wi,Mi表示每个物品的体积,价值与数量,Mi=1表示至多取一件,Mi>1表示至多取Mi件,Mi=-1表示数量无限

 输出描述

1个数Ans表示所装物品价值的最大值

样例输入

2 10

3 7 2

2 4 -1

样例输出

22

参考程序

#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

using namespace std;

int v,n;

int w[100],c[100],m[100];

int f[600];

int main()

{

scanf("%d%d",&n,&m);

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

   scanf("%d%d%d",&w[i],&c[i],&m[i]);

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

   if(m[i]==-1)

     for(int j=w[i];j<=v;j++)

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

   else

     for(int j=1;j<=m[i];j++)

       for(int k=v;k>=w[i];k--)

         f[k]=max(f[k],f[k-w[i]]+c[i]);

printf("%d",f[v]);

return 0;

 } 

 

混合背包

原文:http://www.cnblogs.com/z360/p/6365864.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!