背包模板

来源:互联网 发布:淘宝网店客服中心 编辑:程序博客网 时间:2024/05/23 19:17

模板:

[cpp] view plain copy
  1. /** 
  2. *  多重背包: 
  3. *  有N种物品和一个容量为 V的背包。第i种物品最多有 num[i]件可用, 
  4. * 每件耗费的空间是C[i],价值是W[i]。 
  5. * 求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大。 
  6. */  
  7. #include <iostream>  
  8. #include <cstring>  
  9. #include <algorithm>  
  10. using namespace std;  
  11. #define maxn 100005  
  12. int c[maxn], w[maxn], num[maxn];//c:费用 w:价值 num:数量  
  13. int dp[maxn];    //当前位置符合题意的最优解         
  14. int V;               //V:总容量  
  15.   
  16. //01背包  
  17. void ZeroOnePack(int c, int w)  
  18. {  
  19.     for (int v = V; v >= c; v--)  
  20.     {  
  21.         dp[v] = max(dp[v], dp[v - c] + w);  
  22.     }  
  23. }  
  24. //完全背包  
  25. void CompletePack(int c, int w)  
  26. {  
  27.     for (int v = c; v <= V; v++)  
  28.     {  
  29.         dp[v] = max(dp[v], dp[v - c] + w);  
  30.     }  
  31. }  
  32. //多重背包  
  33. void MultiplePack(int c, int w, int num)  
  34. {  
  35.     if (c * num >= V)  
  36.     {  
  37.         CompletePack(c, w);  
  38.     }  
  39.     else  
  40.     {  
  41.         int k = 1;  
  42.         while (k < num)  
  43.         {  
  44.             ZeroOnePack(k*c, k*w);  
  45.             num -= k;  
  46.             k <<= 1;  
  47.         }  
  48.         ZeroOnePack(num*c, num*w);  
  49.     }  
  50. }  
  51. int main()  
  52. {  
  53.     int t;  
  54.     cin>>t   
  55.     while (t--)  
  56.     {  
  57.         int n;  
  58.         scanf("%d%d", &V, &n);  
  59.         for (int i = 1; i <= n; i++)  
  60.             cin>>c[i]>>w[i]>>num[i];  
  61.         memset(dp, 0, sizeof(dp));  
  62.         for (int i = 1; i <= n; i++)  
  63.             MultiplePack(c[i], w[i], num[i]);  
  64.         cout<<dp[V];  
  65.     }  
  66.     return 0;  
  67. }  


01背包:

[cpp] view plain copy
  1. /*  
  2. 01背包问题  
  3. 01背包问题的特点是,每种物品仅有一件,可以选择放或不放。  
  4. 01背包问题描述:  
  5. 有N件物品和一个容量为 V的背包。第i件物品的重量是w[i],价值是v[i]。  
  6. 求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。 
  7. poj 3624  
  8. */    
  9. #include<iostream>  
  10. #define N 1000005  
  11. #include<algorithm>  
  12. #include<cstring>  
  13. using namespace std;      
  14. int w[N],v[N],dp[N];    
  15. int main()    
  16. {    
  17.     int i, j, n, m;    
  18.     while(cin>>n)  //n件物品   
  19.     {    
  20.         cin>>m;//容积为m   
  21.         memset(dp,0,sizeof(dp));   
  22.         for(i=0; i<n; i++)    
  23.             cin>>w[i]>>v[i];//w[i]为重量,v[i]为价值    
  24.         for(i=0; i<n; i++)    
  25.         {    
  26.             for(j=m; j>=w[i]; j--) //选与不选两条途径   
  27.                 dp[j] = max(dp[j], dp[j-w[i]]+v[i]);    
  28.         }    
  29.         cout<<dp[m];  
  30.     }    
  31.     return 0;    
  32. }    

完全背包:

[cpp] view plain copy
  1. /*  
  2. 完全背包问题的特点是,每种物品可以无限制的重复使用,可以选择放或不放。  
  3. 完全背包问题描述:  
  4. 有N物品和一个容量为 V的背包。第i件物品的重量是w[i],价值是v[i]。  
  5. //此代码为HDU1114;  
  6. */    
  7. #include <iostream>    
  8. #include <algorithm>  
  9. #define INF 0x3fffffff    
  10. #define N 10047    
  11. using namespace std;  
  12. int dp[N],v[N],w[N];    
  13. int main()    
  14. {    
  15.     int t,i,j,k,e,f,m,n;    
  16.     cin>>t;   
  17.     while(t--)    
  18.     {    
  19.         cin>>e>>f;    
  20.         int c = f-e;    
  21.         for(i = 0 ; i <= c ; i++)    
  22.             dp[i]=INF;    
  23.         cin>>n;    
  24.         for(i = 0 ; i < n ; i++)    
  25.         {    
  26.             cin>>v[i]>>w[i];//v[i]为价值,w[i]为重量    
  27.         }    
  28.         dp[0]=0;  
  29.         //注意初始化(要求恰好装满背包,那么在初始化时除了dp[0]为0其它f[1..V]均设为-∞,    
  30.         //这样就可以保证最终得到的dp  是一种恰好装满背包的最优解。    
  31.         //如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将f[0..V]全部设为0)    
  32.         for(i =0 ; i < n ; i++)  //n为物品种类数   
  33.         {    
  34.             for(j = w[i] ; j <= c ; j++)  //c为最大容积   
  35.             {    
  36.                 dp[j] = min(dp[j],dp[j-w[i]]+v[i]);//此处求的是最坏的情况所以用min,确定最少的钱   
  37.             }    
  38.         }    
  39.         if(dp[c] == INF)    
  40.             printf("This is impossible.\n");    
  41.         else    
  42.             printf("The minimum amount of money in the piggy-bank is %d.\n",dp[c]);    
  43.     }    
  44.     return 0;    
  45. }    
  46.    
多重背包:

[cpp] view plain copy
  1. //多重背包(MultiplePack): 有N种物品和一个容量为 V的背包。    
  2. //第i种物品最多有num[i]件可用,每件费用是pre[i],价值是w[i]。    
  3. //求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,    
  4. //且价值总和最大。     
  5. //hdu 2191   
  6. #include<iostream>    
  7. #include<algorithm>    
  8. #include<cstring>  
  9. #define N 1005    
  10. using namespace std;  
  11. int main()    
  12. {    
  13.     int t,n,m,i,j,k;    
  14.     int w[N],pri[N],num[N],dp[N];//dp存的是当前符合题意最大价值,pre[i]所需容积,w[i]价值;   
  15.     while(cin>>t)  
  16.     {    
  17.         while(t--)    
  18.         {    
  19.             memset(dp,0,sizeof(dp));    
  20.             cin>>n>>m;//n为总金额,m为大米种类    
  21.             for(i = 0 ; i < m ; i++) //m种类总数   
  22.             {    
  23.                 cin>>pri[i]>>w[i]>>num[i];//num[i]为每种物品的数量,pre[i]所需容积,w[i]价值   
  24.             }    
  25.             for(i = 0 ; i < m ; i++) // m为总种类数   
  26.             {    
  27.                 for(j = 0 ; j < num[i] ; j++)  //num[i]为每种物品的数量,  
  28.                 {    
  29.                     for(k = n ; k >= pri[i]; k--)  //pre[i]所需容积  
  30.                     {    
  31.                         dp[k] = max(dp[k],dp[k-pri[i]]+w[i]);    
  32.                     }    
  33.                 }    
  34.             }    
  35.             cout<<dp[n]<<endl;    
  36.         }    
  37.     }    
  38.     return 0;    
  39. }    
原创粉丝点击