本来周五要完成0-1背包问题,由于自己的某些事情耽搁.以后要严格要求自己喽!!! 下面我们一起来学习0-1背包问题:
问题描述:
有N件物品和一个容量为c的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使价值总和最大。之所以称为”0-1背包问题”表示该问题只有两种结果:装或者不装即0或者1.
基本思路:
该问题中,每一种物品只有一件,同时选择只有放和不放.
实现过程需要借助一个二维数组m[N+1][c+1],m[i][j]表示i号物品在容量为j时,放或者不放入时的最大价值.
我采用的是从最后一个物品开始分析,即从下至上分析.
首先给出一组数据:
总共物品数目:N=5 背包容量:c = 10
每个物品的重量w[6] = { 0 , 2 , 2 , 6 , 5 , 4 }
每个物品的价值v[6] = { 0 , 6 , 3 , 5 , 4 , 6 }
定义数组m[6][11]:
其中第0位,置为0,不参与计算,只是便于与后面的下标进行统一,无特别用处,也可不这么处理。因为物品总数为5,背包的最大容量为10,那么在设置数组m大小时,可以设行列值为6和11,那么,对于m(i,j)就表示可选物品为i…n背包容量为j(总重量)时背包中所放物品的最大价值。
过程分析:
1.首先背包初始是空的,任何一个物品都没有装入.
2.我们从最后一个物品开始分析,即在重量为0~10时,如何放置物品n,使其中价值最大,此时需要确定m[5][0~10]这11个元素的值.
如果物品的重量w[5]大于当前背包的剩余容量j,则背包不能放入该物品,即此时价值为m[5][j]=0;否则可以放入该物品,即此时价值为该物品的价值v[5].3.接下来我们来分析前n-1个物品在j=0~10的情况下是否放入背包.此时每一个物品的分析都是建立在上一个物品的基础上的,以4号物品为例:
m[4][0~10]这11个值的确定,需要建立在5号物品的基础上.同样分为两种情况:第一种w[4]>j,则背包不能装入该物品,因此此时的最大价值为上一个物品的在j值下对应的值即m[4][j]=m[5][j];第二种w[4]<=j,则背包可以放入该物品,此时就需要比较放入后的价值大,还是不放的价值大.4.和4号物品的分析方法一样,完成剩下的物品在m数组中的对应值.
总结来讲就是:
w[i]>j,则m[i][j]=m[i+1][j];
w[i]<=j, 则m[i][j]=max ( m[i+1][j] , v[i]+m[i+1][j-w[i]]).
以上内容综合起来表达如下图所示:
实现的代码如下:
/*************************************************************************
** > Name : 0_1.c
** > Author: LiYingXiao (Sweethreart502)
** > Mail : liyingxiao502@gmail.com
** > Blog : http://blog.csdn.net/u013166575
** > Created Time: 2015年11月21日 星期六 23时41分19秒
************************************************************************/
#include <stdio.h>
// 五个物品的对应重量
int w[6] = { 0 , 2 , 2 , 6 , 5 , 4 } ;
// 五个物品的对应价值
int v[6] = { 0 , 6 , 3 , 5 , 4 , 6 } ;
// 背包总容量
int c = 10 ;