完全背包问题描述:有编号分别为a,b,c,d的四件物品,它们的重量分别是2,3,4,7,它们的价值分别是1,3,5,9,每件物品数量无限个,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
分析:物品数量无限个,则在取完一种物品后,还要看是否还能再取该物品,以及取了该物品后背包中总物品的价值和不取该物品后背包中总物品的价值,递推公式为status[i][j]=Max{status[i - 1][j],status[i][j - arr[i]] + value[i]}。
int Rec_BackPackCP(vector<int> arr, int value[], int w, int i) {
if (i == 0) {
if (arr[0] <= w) {
return value[0] * (w / arr[0]);
}
else { return 0; }
}
else if (w < arr[i]) {
return Rec_BackPackCP(arr, value, w, i - 1);
}
else {
int a = Rec_BackPackCP(arr, value, w, i - 1);
int c = Rec_BackPackCP(arr, value, w - arr[i], i ) + value[i];
return a > c ? a : c;
}
}
2.使用数组动态规划。使用这种方法要先初始化2种情况时的相应数组元素值。1.在背包所能承载重量为0时。2.在只有一种物品时。
int NORec_BackPackCP(vector<int> arr, int value[], int w) {
//申请内存,保存状态
int **status = new int*[arr.size()];
for (int i = 0;i < arr.size();i++) status[i] = new int[w + 1];
//初始化
for (int i = 0;i < arr.size();i++)status[i][0] = 0;
for (int i = 0;i <= w;i++) {
status[0][i] = value[0] * (i / arr[0]);
}
for (int i = 1;i < arr.size();i++) {
for (int j = 1;j < w + 1;j++) {
if (j < arr[i]) status[i][j] = status[i - 1][j];
else
{
status[i][j] = status[i - 1][j] > (status[i][j - arr[i]] + value[i]) ? status[i - 1][j] : (status[i][j - arr[i]] + value[i]);
}
}
}
return status[arr.size()-1][w];
}
我这里使用的是二维数组,还有人用一维数组https://blog.csdn.net/qq_38749759/article/details/77886770