背包非递归解法

来源:互联网 发布:淘宝黑色锁骨链 编辑:程序博客网 时间:2024/05/17 08:37
 10:  #include <iostream>
  11:  #include <iomanip>
  12:  using namespace std;
  13:   
  14:   
  15:   
  16:  const int n = 4;
  17:  const int W = 5;
  18:   
  19:  int c[n+1][W+1];
  20:   
  21:  /*
  22:  input:
  23:      int v[]:物品的价值数组;
  24:      int w[]:物品重量数组;
  25:      int n:物品个数;
  26:      int W:背包容量;
  27:  
  28:  */
  29:  void knapsack_0_1_problem(int v[],int w[], int n, int W)
  30:  {
  31:      c[0][0] = 0;
  32:      //c[i][j]表示,将i个物品放入容量为j的背包中所具有的价值最大值;
  33:      for (int i=1; i<n; i++)
  34:      {
  35:          c[i][0] = 0;//如果背包容量为0,那么i个物品放入该背包的最优值都是0;
  36:      }
  37:      for (int j=1; j<W; j++)
  38:      {
  39:          c[0][j] = 0;//如果物品的数量为0,那么将0个物品放入大小为j的背包中的最优值就是0;
  40:      }
  41:   
  42:      //下面开始使用递归公式求解最优值
  43:      for(int i=1; i<=n;i++)
  44:      {
  45:          for (int ww=1; ww<=W; ww++)
  46:          {
  47:              //如果当前物品的重量大于背包的体积
  48:              if (w[i]>ww)
  49:              {
  50:                  c[i][ww] = c[i-1][ww];
  51:              }
  52:              else
  53:              {
  54:                  if (c[i-1][ww] > (v[i]+c[i-1][ww-w[i]]))
  55:                  {
  56:                      c[i][ww] = c[i-1][ww];
  57:                  }
  58:                  else
  59:                  {
  60:                      c[i][ww] = v[i]+c[i-1][ww-w[i]];
  61:                  }
  62:              }
  63:          }
  64:   
  65:      }
  66:  }
  67:   
  68:   
  69:   
  70:  int main()
  71:  {
  72:   
  73:      //v[]和w[]分别为价值数组和重量数组,并且下标都是从1开始算的,第0个元素设为-999;
  74:      //这里要下标必须从1开始,因为在迭代的过程当中有c[i][j]=max{c[i-1][j], c[i-1][j-w[i]]},
  75:      //如果元素的下标从0开始取的话,我们在遍历物品价值和重量数组的时候,就会有c[0][j]=max{c[i-1][j], c[-1][j-w[0]]},这里就会出现数组下标为0的情况,
  76:      //所以下标选择从1开始。
  77:      int v[n+1] = {-999, 6, 7, 14, 8};
  78:      int w[n+1] = {-999, 1, 2, 4, 5};
  79:   
  80:      knapsack_0_1_problem(v,w,n,W);
  81:   
  82:      for (int i=0; i<=n; i++)
  83:      {
  84:          for (int j=0; j<=W; j++)
  85:          {
  86:              cout << setw(3) << c[i][j];
  87:          }
  88:          cout << endl;
  89:      }
  90:   
  91:      int remainspace = W;//该变量用来记录背包当前还剩余的容量
  92:   
  93:      //以下过程,从c[n][W]开始向前寻找,那些物品被选择装进背包中;
  94:      //判断条件为:如果第n个物品被选择装进背包中,那么c[n][W]=c[n-1][W-w[n]] + v[n];此时reminspace将变为remainspace-w[n]
  95:      //否则物品n没有被选择,此时背包剩余的容量remainspace不会发生改变;
  96:      //按照上述方法一直往前找,即可以将所有装入背包中物品找到。
  97:   
  98:      for(int i=n; i>=1; i--)
  99:      {
 100:   
 101:          if (remainspace >= w[i])
 102:          {
 103:              
 104:              if ((c[i][remainspace]-c[i-1][remainspace-w[i]]==v[i]))
 105:              {
 106:                  cout << "item " << i << " is selected!" << endl;

107: remainspace = remainspace - w[i];//如果第i个物品被选择,那么背包剩余容量将减去第i个物品的重量 ;

//,2012年5月2日21:45:33 修改为remainspace - w[i];以前为 W-w[i];

 108:              }
 109:          }
 110:                  
 111:      }
 112:   
 113:      cout << "Maximum values is " << c[n][W] << endl;
 114:   
 115:      return 0;
 116:  }
 10:  #include <iostream>  11:  #include <iomanip>  12:  using namespace std;  13:     14:     15:     16:  const int n = 4;  17:  const int W = 5;  18:     19:  int c[n+1][W+1];  20:     21:  /*  22:  input:  23:      int v[]:物品的价值数组;  24:      int w[]:物品重量数组;  25:      int n:物品个数;  26:      int W:背包容量;  27:    28:  */  29:  void knapsack_0_1_problem(int v[],int w[], int n, int W)  30:  {  31:      c[0][0] = 0;  32:      //c[i][j]表示,将i个物品放入容量为j的背包中所具有的价值最大值;  33:      for (int i=1; i<n; i++)  34:      {  35:          c[i][0] = 0;//如果背包容量为0,那么i个物品放入该背包的最优值都是0;  36:      }  37:      for (int j=1; j<W; j++)  38:      {  39:          c[0][j] = 0;//如果物品的数量为0,那么将0个物品放入大小为j的背包中的最优值就是0;  40:      }  41:     42:      //下面开始使用递归公式求解最优值  43:      for(int i=1; i<=n;i++)  44:      {  45:          for (int ww=1; ww<=W; ww++)  46:          {  47:              //如果当前物品的重量大于背包的体积  48:              if (w[i]>ww)  49:              {  50:                  c[i][ww] = c[i-1][ww];  51:              }  52:              else  53:              {  54:                  if (c[i-1][ww] > (v[i]+c[i-1][ww-w[i]]))  55:                  {  56:                      c[i][ww] = c[i-1][ww];  57:                  }  58:                  else  59:                  {  60:                      c[i][ww] = v[i]+c[i-1][ww-w[i]];  61:                  }  62:              }  63:          }  64:     65:      }  66:  }  67:     68:     69:     70:  int main()  71:  {  72:     73:      //v[]和w[]分别为价值数组和重量数组,并且下标都是从1开始算的,第0个元素设为-999;  74:      //这里要下标必须从1开始,因为在迭代的过程当中有c[i][j]=max{c[i-1][j], c[i-1][j-w[i]]},  75:      //如果元素的下标从0开始取的话,我们在遍历物品价值和重量数组的时候,就会有c[0][j]=max{c[i-1][j], c[-1][j-w[0]]},这里就会出现数组下标为0的情况,  76:      //所以下标选择从1开始。  77:      int v[n+1] = {-999, 6, 7, 14, 8};  78:      int w[n+1] = {-999, 1, 2, 4, 5};  79:     80:      knapsack_0_1_problem(v,w,n,W);  81:     82:      for (int i=0; i<=n; i++)  83:      {  84:          for (int j=0; j<=W; j++)  85:          {  86:              cout << setw(3) << c[i][j];  87:          }  88:          cout << endl;  89:      }  90:     91:      int remainspace = W;//该变量用来记录背包当前还剩余的容量  92:     93:      //以下过程,从c[n][W]开始向前寻找,那些物品被选择装进背包中;  94:      //判断条件为:如果第n个物品被选择装进背包中,那么c[n][W]=c[n-1][W-w[n]] + v[n];此时reminspace将变为remainspace-w[n]  95:      //否则物品n没有被选择,此时背包剩余的容量remainspace不会发生改变;  96:      //按照上述方法一直往前找,即可以将所有装入背包中物品找到。  97:     98:      for(int i=n; i>=1; i--)  99:      { 100:    101:          if (remainspace >= w[i]) 102:          { 103:               104:              if ((c[i][remainspace]-c[i-1][remainspace-w[i]]==v[i])) 105:              { 106:                  cout << "item " << i << " is selected!" << endl; 107:                  remainspace = remainspace - w[i];//如果第i个物品被选择,那么背包剩余容量将减去第i个物品的重量 ;                                                        //,2012年5月2日21:45:33 修改为remainspace - w[i];以前为 W-w[i]; 108:              } 109:          } 110:                   111:      } 112:    113:      cout << "Maximum values is " << c[n][W] << endl; 114:    115:      return 0; 116:  }



原创粉丝点击