0-1背包问题

一个容积为5的箱子,现在要装入物品,物品一共有4个,体积分别是1、2、3、4,问有几种填充方法。

这个问题很简单,一共有两种填充方法1、4和2、3,这里延伸一下:输入两个整数n和m,从数列1、2、3、4……、n中随意取几个数,使其和等于m,要求将其中所有可能的组合列出来,编程求解。

这里的算法一共有以下4步:

(1)比较n和m哪个大?如果n>m,则把m赋值给n。因为如果n>m,则那些m和n之间的数,是没有意义的。比如m=4,n=7,那么既然n中的5、6、7要比m大,所以是没有意义的。于是把m赋值给n,这样n也等于4,开始比较。

(2)现在我们开始填充箱子,先把体积最大的物品放入,看是否与箱子所剩容积相等。如果相等的话,则说明合适,打印物品。

(3)如果与箱子所剩容积不等,则用容积减去最大物品容积,看次大物品容积是否与箱子所剩容积相等,递归开始,直到物品全部比较完为止。

(4)这里要设计一个0-1背包:0代表没有装入物品,1代表装入该物品。比如一个容积为5的箱子,放入4,可以装入,则f[4] = 1,代表4是装入了,然后3、2,装不下,所以f[3] = f[2] = 0,1可以装入,则f[1] = 1。

源码实现:

#include<iostream> 
#include
<string> 
using namespace std; 

int mVal,nVal; 
int *pOut; 

void calFun(int m,int n) 

    
if(m<1||n<1||(n==1&&m!=1)) 
        
return

    
//看是否与箱子所剩容积相等 
    if(m==n) 
    

        pOut[n] 
= 1
        
for(int i = 1;i<=nVal;++i) 
        

            
if(pOut[i]) 
                cout
<<i<<" "
        }
 
        cout
<<endl; 
        pOut[n] 
= 0
    }
 

    calFun(m,n
-1);//不取n 
    pOut[n] = 1
    calFun(m
-n,n-1);//取n 
    pOut[n] = 0
}
 

int main() 

    cout
<<"m:"
    cin
>>mVal; 
    cout
<<"n:"
    cin
>>nVal; 

    pOut 
= new int[nVal+1]; 
    memset(pOut,
0,(nVal+1)*sizeof(int)); 

    calFun(mVal,nVal); 
    delete []pOut; 
    
return 0
}

 

posted @ 2009-09-03 13:50  回忆1919  阅读(1597)  评论(0编辑  收藏  举报