问题描述:
n个物品组成集合O,每个商品有两个属性vi(所占体积)和pi(价格)
背包容量为C
输出商品子集S属于O,使价格最大,体积不超过背包体积
递推公式:(先上后下)


#include<iostream>using namespace std;int v[] = { 0 , 10 , 3 , 4 , 5 , 4 }; //商品的体积10 , 3 , 4 , 5 , 4int p[] = { 0 , 24 , 2 , 9 , 10 , 9 }; //商品的价值24 , 2 , 9 , 10 , 9const int m = 5; //商品数目const int C = 13; //背包大小int dp[m+1][C+1] = { { 0 } }; //动态规划表 dp[i][j] i表示物品序号,j表示背包所剩空间int Rec[m+1][C+1]= { { 0 } }; //动态规划表,用于存储是否选择该商品int item[m+1]; //最优解情况,0为未选择,1为选择void KnapsackDP() { //动态规划for (int i = 0; i <= m; i++)Rec[i][0] = dp[i][0] = 0;for (int i = 0; i <= C; i++)Rec[0][i] = dp[0][i] = 0;for (int i = 1; i <= m; i++) {for (int j = 1; j <= C; j++) {if (j >= v[i] && dp[i - 1][j] < dp[i - 1][j - v[i]] + p[i]){dp[i][j] = dp[i - 1][j - v[i]] + p[i];//构造dp数组,包中装入第i个商品Rec[i][j] = 1; //选则了第i个}else {dp[i][j] = dp[i - 1][j];//最优解向下瞬移Rec[i][j] = 0; //第i个未被选择//if (j >= v[i]) {// if (dp[i - 1][j] < dp[i - 1][j - v[i]] + p[i]){// dp[i][j] = dp[i - 1][j - v[i]] + p[i];// //构造dp数组,包中装入第i个商品// Rec[i][j] = 1; //选则了第i个// }// else {// dp[i][j] = dp[i - 1][j];// Rec[i][j] = 0; //第i个未被选择// }//}//else {// dp[i][j] = dp[i - 1][j];// Rec[i][j] = 0;}}}}void IsSelect(int i, int j) { //解析最优解if (i > 0) {if (Rec[i][j]>0) {item[i] = 1;}elseitem[i] = 0;IsSelect(i - 1, j - v[i]);}}void Print() {for (int i = 0; i <= m; i++) { //输出dp数组for (int j = 0; j <= C; j++) {cout << dp[i][j] << "\t";}cout << endl;}cout << endl;for (int i = 0; i <= m; i++) { //输出Rec数组for (int j = 0; j <= C; j++) {cout << Rec[i][j] << "\t";}cout << endl;}cout << endl;for (int i = 1; i <= m; i++)cout << item[i] << " ";cout << endl;}int main(){KnapsackDP();IsSelect(m, C);Print();return 0;}
运行结果:
