01背包 和 完全背包

原创 2018年04月16日 00:42:43

题目:有价值为v[i]、重量为w[i]的N个物品(每个物品仅有一个)及容量为W的背包,现要求在物品总重量不超过W的前提下选择总价值尽可能高的物品放进背包里。

分析用一个二维数组T[i][j]表示背包的容量为j,物品数为1~i时的最大价值,T[i][j]只有选择第i种物品或者不选第i种物品两种可能,因此状态方程可写成T[i][j]=max(T[i-1][j],T[i-1][j-w[i]]+v[i]),其中前一种是不选第i种物品,后一种是选择第i种物品。

这种方法时间和空间复杂度都是O(N*W), 空间复杂度可以优化到O(W), 即使用一维数组, 代码如下:

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

    {  
        for(int j = W; j >= w[i]; j--)  
        {  
			T[j]=max(T[j],T[j-w[i]]+v[i]);
		}
 	}

一般求最优解有两种问法: 恰好装满背包和重量不超过背包,而它们的初始化是不同的。

1.恰好装满背包,除了T[0]=0外T[1....W]均为-∞, 如果不能恰好装满背包,则T[W] =-∞ , 则说明没有最优解。

2.重量不超过背包,T[0....W]均初始化为0。

附上题目代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int Max=1000+5;
int w[Max],v[Max],T[Max];
int main()
{
    int N,W;
    cin>>N>>W;
for(int i=1;i<=N;i++)
{
    cin>>v[i]>>w[i];
for(int i=0;i<=W;i++)T[i]=0;
for(int i=1;i<=N;i++)
for(int j=W;j>=w[i];j--)
{
    T[j]=max(T[j],T[j-w[i]]+v[i]);
}
    cout<<T[W]<<endl;
    return 0;
}                            

把题目改为恰好装满背包,代码如下(注意与上述代码不同之处)

#include<iostream>
#include<algorithm>
using namespace std;
const int Max=1000+5;
const int INFTY=-1000000; 
int w[Max],v[Max],T[Max];
int main()
{
int N,W;
cin>>N>>W;
for(int i=1;i<=N;i++)
{
	cin>>v[i]>>w[i];
}
for(int i=1;i<=W;i++)T[i]=INFTY;
T[0]=0;
for(int i=1;i<=N;i++)
	for(int j=W;j>=w[i];j--)
	{
		T[j]=max(T[j],T[j-w[i]]+v[i]);
	}
	if(T[W]<0)
	cout<<"It's impossible!"<<endl;
	else
	cout<<T[W]<<endl;
return 0;
 } 

题目再次修改,如果每件物品都有无穷多件,则为完全背包问题。每种物品有多种选择,选0件、1件……n件(不超过背包能装的重量),  用二维数组表示T[i][j]=max(T[i-1][j-k*w[i]] + k*v[i]), 0<= k*w[i]<= W。实际上,确是直接使用一维数组,即如果当前背包未满,继续往里装第i种物品。

for(int i=1;i<=N;i++)
	for(int j=w[i];j<=W;j++)
	{
	    T[j]=max(T[j],T[j-w[i]]+v[i];
	}

发现完全背包问题跟01背包的区别在于内层循环的顺序不同。

例题1:01背包 HDU2602

例题2:完全背包 HDU1114



史上最易懂的01背包,完全背包,多重背包讲解

背包之01背包、完全背包、多重背包详解   PS:大家觉得写得还过得去,就帮我把博客顶一下,谢谢。 首先说下动态规划,动态规划这东西就和递归一样,只能找局部关系,若想全部列出来,是很难的,比如汉诺塔。...
  • qq_34374664
  • qq_34374664
  • 2016-08-17 14:02:35
  • 3365

[动态规划] 01背包与完全背包

01背包(每种物品的状态为选择或不选择,最多只能选1件): 1.传统的二维数组,第i件物品的重量为w[i],价值为v[i] dp[i][j]保存的是选择前i件物品(每一件物品的状态为选与不选),在...
  • sr19930829
  • sr19930829
  • 2014-11-08 09:40:57
  • 2346

01背包与完全背包微妙的区别

01背包跟完全背包微妙的区别: //完全背包 void solve1() { memset(d, 0, sizeof(d)); for(int i = 0; i < N; i++) for...
  • u011044487
  • u011044487
  • 2014-03-02 14:04:07
  • 1071

01背包,完全背包,多重背包的个人总结

大一刚接触背包问题的时候就觉得绕。那时候真的是一点代码基础都没有强行去理解。每次都是以失败告终,一直到大二都还不会写背包问题。 后来某次模拟赛之后碰到了背包问题,觉得这个还是挺简单的,终于是下定决心准...
  • tinyguyyy
  • tinyguyyy
  • 2016-04-20 22:08:53
  • 7090

背包问题——01背包、完全背包、多重背包、混合三种背包问题

转自: http://apps.hi.baidu.com/share/detail/14968747 P01: 01背包问题 题目 有N件物品和一个容量为V的背包。第i...
  • hcwzq
  • hcwzq
  • 2011-08-04 21:26:43
  • 1782

背包问题详解(01背包,完全背包,多重背包,混合背包,二维费用背包……)

  • 2010年10月16日 22:21
  • 124KB
  • 下载

经典背包问题----(01背包、完全背包、多重背包)

最近在学DP,上周六ACM集训队花一整天的时间共同探讨了最经典的DP--背包问题,对这类问题研究也挺深入的,感谢各队友及老师的讲解,觉得受益匪浅! (1)01背包 01背包算是最基础的背包...
  • AHH_AHHH
  • AHH_AHHH
  • 2017-10-31 19:34:33
  • 52

背包问题详解:01背包、完全背包、多重背包

参考链接: http://www.cnblogs.com/fengty90/p/3768845.html http://blog.csdn.net/mu399/article/details/7722...
  • na_beginning
  • na_beginning
  • 2017-03-17 11:47:48
  • 14619

几道有关钱币的背包问题分析

  • 2016年04月05日 09:35
  • 34KB
  • 下载

动态规划01背包与完全背包的C语言实现

01背包是基础的背包问题,即容量为v的背包, 给你n件物品, 每件物品只有一件, 每件物品所占体积vi, 价值wi已知,求此背包所能容纳的前提下,让在其中物品价值最大。 此问题状态方程为发f[i][v...
  • shadowam
  • shadowam
  • 2017-02-10 11:17:05
  • 1300
收藏助手
不良信息举报
您举报文章:01背包 和 完全背包
举报原因:
原因补充:

(最多只允许输入30个字)