0-1背包问题的动态规划解法

来源:互联网 发布:加工中心 自动编程 编辑:程序博客网 时间:2024/06/11 01:49

问题陈述:
给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为c。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大?
在选择装入背包的物品时,对每种物品i只有两种选择,即装入背包或不装入背包。不能将物品i装入背包多次,也不能只装入部分的物品i。因此,该问题称为0-1背包问题。 

问题的数学抽象:
此问题可转化为:给定c>0,wi>0,vi>0,1≤i≤n,要求找出一个n元0-1向量(x1,x2,…,xn),xi∈{0,1},1≤i≤n,使得∑wixi≤c,而且∑vixi达到最大。因此,0-1背包是一个特殊的整数规划问题:
max ∑vixi
s.t. ∑wixi≤c, xi∈{0,1},1≤i≤n

可用动态规划算法求解。
算法c源码

Code:
  1. #include "stdafx.h"   
  2. #define N 10   
  3. #define W 3   
  4. int mv[N][W]; // mv[i][j]记录0~i件物品中,包重量为j的最大价值。   
  5. int pack( int (&w)[N],int (&v)[N])   
  6. {   
  7.   
  8.     for(int i=0;i<W;++i)  mv[0][i]=0;   
  9.     for(int i=0;i<N;++i)  mv[i][0]=0;   
  10.     int j,i;   
  11.   //动态规划求解   
  12.     for(i=1;i<N;++i)   
  13.     {   
  14.        for(j=1;j<W;++j)   
  15.           if( j >= w[i] )   
  16.           {   
  17.            if( mv[i-1][j]< mv[i-1][j-w[i]]+v[i])   
  18.                 mv[i][j] = mv[i-1][j-w[i]]+v[i];   
  19.             else    
  20.                 mv[i][j] = mv[i-1][j];   
  21.            }   
  22.            else mv[i][j] = mv[i-1][j];   
  23.     }   
  24.     return  mv[N-1][W-1];   
  25. }   
  26. int main()   
  27. {      
  28.     int w[N]={0,2,3,4,5,6,7,8,9,10},v[N]={0,9,2,3,4,5,2,4,5,3};   
  29.     printf("%d",pack(w,v));   
  30.     return 0;   
  31. }  

文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppjs/2008823/137176.html#)