简单背包问题



“背包题目”的基本描述是:有一个背包,能盛放的物品总重量为S,设有N件物品,其重量分别为w1,w2,…,wn,希看从N件物品中选择若干物品,所选物品的重量之和恰能放进该背包,即所选物品的重量之和即是S。

递归代码:

[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <stdlib.h>  
  4. using namespace std;  
  5.   
  6. const int N = 7;//物品数量  
  7. const int S = 20;//能盛放的物品总重量  
  8. int w[N+1] = {0, 1, 4, 3, 4, 5, 2, 7};  
  9.   
  10. int knap(int s,  int n) //s为剩余重量,n为剩余可先物品数。 
  11. {  
  12.     if(s == 0)  
  13.     {  
  14.         return 1;  
  15.     }  
  16.   
  17.     if(s<0 || (s>0&&n<1))  
  18.     {  
  19.         return 0;  
  20.     }  
  21.   
  22.     //第n个物品入选  
  23.     if(knap(s-w[n], n-1))  
  24.     {  
  25.         cout << w[n] << " ";  
  26.         return 1;  
  27.     }  
  28.   
  29.     //第n个物品没入选  
  30.     return knap(s, n-1);      
  31. }  
  32.   
  33. int main(int argc, char *argv[])  
  34. {  
  35.     if(knap(S, N))  
  36.     {  
  37.         cout << endl << "OK" << endl;  
  38.     }  
  39.     else  
  40.     {  
  41.         cout << "NO" << endl;  
  42.     }  
  43.   
  44.     system("PAUSE");   
  45.     return 0;  
  46. }  

 

非递归代码:

[cpp]  view plain copy
  1. // ---------------------------------------------------  
  2. //  注1: 一般要求一个解,此程序是得到所有解  
  3. //  注2: 由于32位unsigned int限制,最多32个物品                          
  4. // ---------------------------------------------------  
  5.   
  6. #include "stdafx.h"  
  7. #include <iostream>  
  8. using namespace std;  
  9.   
  10. // 物品总数  
  11. const int N_ITEM = 5;  
  12.   
  13. // 背包能装的重量  
  14. const int BAG = 15;  
  15.   
  16. // 初始化每个物品的重量  
  17. int item[N_ITEM] = {2, 3, 5, 7, 8};  
  18.   
  19. // 标记数组  
  20. int flag[N_ITEM] = {0, 0, 0, 0, 0};  
  21.   
  22. // 结果计数器  
  23. int resultCount = 0;  
  24.   
  25. // 打印结果  
  26. void Print();  
  27.   
  28. int main()  
  29. {  
  30.     // 打印已知条件  
  31.     cout << "BAG Weight:" << BAG << endl;  
  32.     cout << "Item Number:" << N_ITEM << endl;  
  33.   
  34.     for (int i=0; i!=N_ITEM; i++)  
  35.     {  
  36.         cout << "Item." << i+1 << " W=" << item[i] << "\t";  
  37.     }  
  38.   
  39.     cout << endl;  
  40.   
  41.     unsigned int count = 0;  
  42.     unsigned int all_count = 1;  
  43.   
  44.     for (int i=0; i!=N_ITEM; i++)  
  45.     {  
  46.         all_count *= 2;//all_count记录可能解的个数  
  47.     }  
  48.   
  49.     while (1)  
  50.     {  
  51.         // 模拟递归...列举所有flag数组可能  
  52.         // 其实就这个for循环是关键  
  53.         for (int i=0; i!=N_ITEM; i++)  
  54.         {  
  55.             if ( 0 == flag[i] )  
  56.             {  
  57.                 flag[i] = 1;  
  58.                 continue;  
  59.             }             
  60.             else   
  61.             {  
  62.                 flag[i] = 0;  
  63.                 break;  
  64.             }  
  65.         }  
  66.           
  67.         // 本次重量,初始化0  
  68.         int temp = 0;  
  69.   
  70.         // 按标记计算所有选中物品重量和  
  71.         for (int i=0; i!=N_ITEM; i++)  
  72.         {  
  73.             if ( 1 == flag[i] )  
  74.             {  
  75.                 temp += item[i];  
  76.             }  
  77.         }  
  78.   
  79.         // 满足背包重量就打印  
  80.         if ( temp == BAG )  
  81.         {  
  82.             resultCount++;  
  83.             Print();  
  84.         }         
  85.   
  86.         // 如果遍历了所有情况就break掉while(1)循环  
  87.         count++;  
  88.         if (count == all_count)  
  89.         {  
  90.             break;  
  91.         }  
  92.     }  
  93.   
  94.     return 0;  
  95. }  
  96.   
  97. void Print()  
  98. {  
  99.     cout << "Result " << resultCount << endl;  
  100.   
  101.     for (int i=0; i!=N_ITEM; i++)  
  102.     {  
  103.         if ( 1 == flag[i] )  
  104.         {  
  105.             cout << "Item." << i+1 << "  Weight:" << item[i] << "\t";  
  106.         }  
  107.     }  
  108.   
  109.     cout << endl;  
  110. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值