背包问题----一步一步来

题目:

N种物品和一个容量为V的背包,每种物品都有一件。第i种物品的容量是v[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的容量总和不超过背包容量,且价值总和最大。 

下面以这些数据来演示过程:V=10(即总容量为10);


步骤一:

假设现在只有w[1](只有一件物品,这里从第一件开始),分别用V=0,1,2,3.......10容量的背包去装它,计算对应的价值。(如图);


说明:v[1]=2,,w[i]=6;

对于V=0,1时,小于2,都装不下,所以价最大值都为0,对于V=2,3,4,5,6,7,8,9,10;都可以装下;所以最大价值都为6;这样就算出了只有一件物品时,分别用V=0,1,2,3,4.....10的背包去装它所得到的最大价值。

步骤二:

假设现在只有w[1],w[2](只有两件物品),因为第一件物品已经讨论过,现在从第二件开始,分别用V=0,1,2,3.......10容量的背包去装它,计算对应的价值。(如图);


说明:v[2]=4;w[2]=4;

对应V=0,1;还是装不了这两件中的任意一件或者全部;V=2,3:显然装不了第二件,但是能装下第一件,所以对于容量V= 2,3时,在只有第一,二件物品的情况,最大价值为装第一件的价值。

当V=4时,4=w[2]=4:显然是可以装下第二件,这时就要判断该不该装入第二件,假设装入:对与V=4;如果装入第二件:则剩下的容量为0:那我们找到V=0时,装入第一件的最大价值为0;那么如果把第二件装入得到的价值为:0+4=4;显然小于只装入第一件时的价值:所以对于V=4;在只有两件物品的情况下只装入第一件价值最大。

V=5时:同上。

当V=6时:显然可以装下第二件物品,假设装入:则剩下的容量为2,那我们找到V=2时,装入第一件的最大价值为6;那么如果装入第二件,得到的价值为:6+4=10;显然大于只装入第一件时的价值:所以对于V=6;只有两件物品的情况下,装入第一,二件价值最大。

V=7,8,9,10:同上。

这样就算出了只有两件物品时,分别用V=0,1,2,3,4.....10的背包去装它们所得到的最大价值。

步骤三:

假设现在只有w[1],w[2],w[3](只有三件物品),因为第一,二件物品已经讨论过,现在从第三件开始,分别用V=0,1,2,3.......10容量的背包去装它,计算对应的价值。(如图);


说明:

v[3]=1;w[3]=6;

这里分析下(3,7)这个位置;

当V=7时:7>[3]=1,显然可以装下第三件物品,假设装入:则剩下的容量为6,那我们找到V=6时,有两件的情况下;价值为6;那么装入第三件得到的价值为:6+6=12;显然大于只装前两件时的价值:所以对于V=7;只有三件物品的情况下,装入第一,二,三件价值最大。.........

这样就算出了只有三件物品时,分别用V=0,1,2,3,4.....10的背包去装它们所得到的最大价值。

后面的步骤后前面步骤一样了。

最终结果:(如图)


最后得到:容量为10的背包装入五件物品得到的最大价值为:17.

代码:

#include<iostream>
#include <cstring>  
using namespace std;
#include <iomanip>
#define	 V 10

int m[8][13];

  int main(){
  	
    memset(m,0,sizeof(m)); //初始化 
    
	int n=5;
	 int v[6]={0,6,4,6,3,1};  
     int w[6]={0,2,4,1,5,3};  
     
     //计算 
for(int i=1;i<=n;i++){
	for(int j=1;j<=V;j++){
		if(j>=w[i])
			m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]);
		
		else
			m[i][j]=m[i-1][j];
	}
}
    
    //输出 
   for(int i=1;i<=n;i++)  
    {  
        for(int j=1;j<=V;j++)  
        {  
            cout<<setw(3)<<m[i][j];  
        }  
        cout<<endl;  
    }  

	return 0;
}

结果:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值