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

递推公式:(先上后下)

image.png
image.png

  1. #include<iostream>
  2. using namespace std;
  3. int v[] = { 0 , 10 , 3 , 4 , 5 , 4 }; //商品的体积10 , 3 , 4 , 5 , 4
  4. int p[] = { 0 , 24 , 2 , 9 , 10 , 9 }; //商品的价值24 , 2 , 9 , 10 , 9
  5. const int m = 5; //商品数目
  6. const int C = 13; //背包大小
  7. int dp[m+1][C+1] = { { 0 } }; //动态规划表 dp[i][j] i表示物品序号,j表示背包所剩空间
  8. int Rec[m+1][C+1]= { { 0 } }; //动态规划表,用于存储是否选择该商品
  9. int item[m+1]; //最优解情况,0为未选择,1为选择
  10. void KnapsackDP() { //动态规划
  11. for (int i = 0; i <= m; i++)
  12. Rec[i][0] = dp[i][0] = 0;
  13. for (int i = 0; i <= C; i++)
  14. Rec[0][i] = dp[0][i] = 0;
  15. for (int i = 1; i <= m; i++) {
  16. for (int j = 1; j <= C; j++) {
  17. if (j >= v[i] && dp[i - 1][j] < dp[i - 1][j - v[i]] + p[i]){
  18. dp[i][j] = dp[i - 1][j - v[i]] + p[i];
  19. //构造dp数组,包中装入第i个商品
  20. Rec[i][j] = 1; //选则了第i个
  21. }
  22. else {
  23. dp[i][j] = dp[i - 1][j];//最优解向下瞬移
  24. Rec[i][j] = 0; //第i个未被选择
  25. //if (j >= v[i]) {
  26. // if (dp[i - 1][j] < dp[i - 1][j - v[i]] + p[i]){
  27. // dp[i][j] = dp[i - 1][j - v[i]] + p[i];
  28. // //构造dp数组,包中装入第i个商品
  29. // Rec[i][j] = 1; //选则了第i个
  30. // }
  31. // else {
  32. // dp[i][j] = dp[i - 1][j];
  33. // Rec[i][j] = 0; //第i个未被选择
  34. // }
  35. //}
  36. //else {
  37. // dp[i][j] = dp[i - 1][j];
  38. // Rec[i][j] = 0;
  39. }
  40. }
  41. }
  42. }
  43. void IsSelect(int i, int j) { //解析最优解
  44. if (i > 0) {
  45. if (Rec[i][j]>0) {
  46. item[i] = 1;
  47. }
  48. else
  49. item[i] = 0;
  50. IsSelect(i - 1, j - v[i]);
  51. }
  52. }
  53. void Print() {
  54. for (int i = 0; i <= m; i++) { //输出dp数组
  55. for (int j = 0; j <= C; j++) {
  56. cout << dp[i][j] << "\t";
  57. }
  58. cout << endl;
  59. }
  60. cout << endl;
  61. for (int i = 0; i <= m; i++) { //输出Rec数组
  62. for (int j = 0; j <= C; j++) {
  63. cout << Rec[i][j] << "\t";
  64. }
  65. cout << endl;
  66. }
  67. cout << endl;
  68. for (int i = 1; i <= m; i++)
  69. cout << item[i] << " ";
  70. cout << endl;
  71. }
  72. int main()
  73. {
  74. KnapsackDP();
  75. IsSelect(m, C);
  76. Print();
  77. return 0;
  78. }

运行结果:
image.png