动态规划求解01背包问题
令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;
-
}