01背包

来源:互联网 发布:osx和linux 编辑:程序博客网 时间:2024/06/14 05:44

01背包问题:

有一个体积为V的背包,有n件物品,每件物品的体积,价值分别为w[i],p[i];要从n件物品中选些放入背包中,使背包里物品的总价值最大。

动态方程:c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+p[i]).

有关动态方程方面的代码:

  1. for (int i = 1; i <= n; i++) {      
  2.   for (int j = 1; j <= total_weight; j++) {      
  3.     if (w[i] > j) {      
  4.       c[i][j] = c[i-1][j];      
  5.     }   
  6.     else {                      //也可以用<span style="font-family: KaiTi_GB2312;font-size:18px;">c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+p[i])代替下面的</span>  
  7.         if (c[i-1][j] > v[i]+c[i-1][j-w[i]]) {      
  8.           c[i][j] = c[i-1][j];      
  9.         }      
  10.         else {      
  11.           c[i][j] =  v[i] + c[i-1][j-w[i]];      
  12.         }      
  13.     }      
  14.   }      
  15. }      

在杭电2602中我们就可以很舒服的用01背包解决:

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=2602

初学者代码:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include<cstring>  
  3. #include<cstdio>  
  4. using namespace std;  
  5.   
  6. int c[1011][1011];  
  7. int max(int a,int b)  
  8. {  
  9.     return a>b?a:b;  
  10. }  
  11.   
  12. int knapsack(int m,int n)  
  13. {  
  14.     memset(c,0,sizeof(c));  
  15.     int i,j,val[1001],V[1001];  
  16.     for(i=1;i<=n;i++)  
  17.         scanf("%d",&val[i]);  
  18.     for(i=1;i<=n;i++)  
  19.         scanf("%d",&V[i]);  
  20.     for (i = 1; i <= n; i++)  
  21.         {  
  22.       for (j = 1; j <= m; j++)  
  23.         {  
  24.         if (V[i] > j)  
  25.         {  
  26.         c[i][j] = c[i-1][j];  
  27.         }  
  28.     else  
  29.         {  
  30.            c[i][j]=max(c[i-1][j],c[i-1][j-V[i]]+val[i]);  
  31.         }  
  32.     }  
  33.   }  
  34.   return (c[n][m]);  
  35. }  
  36.   
  37. int main()  
  38. {  
  39.     int t,n,m;  
  40.     scanf("%d",&t);  
  41.     while(t--)  
  42.     {  
  43.         scanf("%d%d",&n,&m);  
  44.         printf("%d\n",knapsack(m,n));  
  45.     }  
  46.     return 0;  
  47. }  




这个问题代码需要优化,减少时间空间复杂度,

(优化后代码)AC代码:

  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. using namespace std;  
  5.   
  6. int c[1011];  
  7.   
  8. int max(int a,int b)  
  9. {  
  10.     return a>b?a:b;  
  11. }  
  12. int knapsack(int m,int n)  
  13. {  
  14.     memset(c,0,sizeof(c));  
  15.     int i,j,val[1001],V[1001];  
  16.     for(i=1;i<n+1;i++)  
  17.         scanf("%d",&val[i]);  
  18.     for(i=1;i<n+1;i++)  
  19.         scanf("%d",&V[i]);  
  20.     for(i=1;i<n+1;i++)  
  21.         for(j=m;j>=V[i];j--)  
  22.             c[j]=max(c[j-V[i]]+val[i],c[j]);  
  23.     return(c[m]);  
  24. }  
  25. int main()  
  26. {  
  27.     int t,n,m;  
  28.     scanf("%d",&t);  
  29.     while(t--)  
  30.     {  
  31.         scanf("%d%d",&n,&m);  
  32.         printf("%d\n",knapsack(m,n));  
  33.     }  
  34.     return 0;  
  35. }  


0 0