令Li,j表示在前j个物体中能够装入载重量为i的背包中的物体的最大价值,i=1,2,…,m。显然,在前j个物体中,能够装入载重量为i的背包中,有些物体可以装入背包,有些物体不能装入背包。于是,可以得到下面的动态规划函数:
- #include<iostream>
- using namespace std;
- #define M 50 // 背包最大载重
- #define N 15 // 最多物体个数
- int p[N+1], w[N+1];
- bool x[N+1];
- int m, n;
- int knapsack(){
- int mz[M+1][N+1];
- int i,j;
- // 初始化
- memset(mz, 0, sizeof(mz));
- memset(x, false, sizeof(x));
- // DP
- for(i=1; i<=m; i++){
- for(j=1; j<=n; j++){
- mz[i][j] = mz[i][j-1]; // 默认为不能放该物体时的最优解
- if(i>=w[j]&&mz[i-w[j]][j-1]+p[j]>mz[i][j]){ // 如果可以放入且放入更优时
- mz[i][j] = mz[i-w[j]][j-1] + p[j]; // 放入
- }
- }
- }
- // 计算放入背包的物体
- for(i=m, j=n; j>0; j--){
- if(mz[i][j]>mz[i][j-1]){ // 如果能取该物体时价值大于不能取该物品
- x[j] = true; i -= w[j]; // 说明该物体被放入了背包
- }
- }
- return mz[m][n];
- }
- int main(){
- int i;
- cout<<"请输入物体个数:";
- cin>>n;
- cout<<"请输入物体重量:";
- for(i=1; i<=n; i++){
- cin>>w[i];
- }
- cout<<"请输入物体价值:";
- for(i=1; i<=n; i++){
- cin>>p[i];
- }
- cout<<"请输入背包载重量:";
- cin>>m;
- cout<<"背包最大价值为"<<knapsack()<<endl;
- cout<<"背包中放入的物体有:";
- for(i=1; i<=n; i++)if(x[i])cout<<i<<" ";
- cout<<endl;
- return 0;
- }