0-1背包问题与完全背包问题C++实现 动态规划

来源:互联网 发布:海盗湾中文域名 编辑:程序博客网 时间:2024/05/01 21:16


今天看了看背包九讲,自己写了下0-1背包和完全背包

王晓东《计算机算法分析与设计》上面给出的C++实现比较繁琐,相比而言这个版本更加简明

给出了测试数据

0-1背包问题C++实现

[cpp] view plaincopy
  1. /*任务:计算0-1背包问题的最大价值 
  2. Sample Input 
  3. 10 4 
  4. 2 1 
  5. 3 3 
  6. 4 5 
  7. 7 9 
  8. Sample Output 
  9. 12 
  10. 0 1 0 1 
  11. */  
  12. #include<stdio.h>  
  13. #include<string.h>  
  14. int c[20][1000];//c[k][y]为只允许装前k种物品,背包总重量不超过y的最大价值  
  15. int inumber[21][1000];//inumber[k][u]为只允许装前K种物品,背包总重量不超过y时得到最大价值时使用的背包的最大标号  
  16. int w[21],p[21];  
  17. int knapsack(int m,int n)  
  18. {  
  19.     int i,j;  
  20.     for(i=1;i<n+1;i++)  
  21.         scanf("%d%d",&w[i],&p[i]);  
  22.     memset(c,0,sizeof(c));  
  23.     memset(inumber,0,sizeof(inumber));  
  24.     for(j=1;j<m+1;j++){  
  25.         c[1][j]=j/w[1]*p[1];  
  26.     }  
  27.     for(i=1;i<n+1;i++){  
  28.         for(j=1;j<m+1;j++){  
  29.             if(j >= w[i]){  
  30.                 if(p[i]+c[i-1][j-w[i]]>=c[i-1][j]){  
  31.                     c[i][j]=p[i]+c[i-1][j-w[i]];  
  32.                     inumber[i][j]=i;  
  33.                 }     
  34.                 else{  
  35.                     c[i][j]=c[i-1][j];  
  36.                     inumber[i][j]=inumber[i-1][j];   
  37.                 }  
  38.             }  
  39.             else{  
  40.                 c[i][j]=c[i-1][j];  
  41.                 inumber[i][j]=inumber[i-1][j];   
  42.             }  
  43.         }  
  44.     }  
  45.     return(c[n][m]);                       
  46. }  
  47.   
  48. void trackSolution(int m, int n){  
  49.     int x[21];  
  50.     int y = m;  
  51.     int j = n;  
  52.     memset(x, 0, sizeof(x));  
  53.     while(true){  
  54.         j = inumber[j][y];  
  55.         x[j] = 1;  
  56.         y = y - w[j];  
  57.         while(inumber[j][y] == j){  
  58.             y = y - w[j];  
  59.             x[j]++;  
  60.         }  
  61.         if(!inumber[j][y]) break;  
  62.     }  
  63.     printf("最大价值方案中各个物品的个数为(物品标号从1到n):");  
  64.     for(j = 1; j <= n; j++){  
  65.         printf("%d ", x[j]);  
  66.     }  
  67.     printf("\n");  
  68. }  
  69. int main()  
  70. {  
  71.     int m,n;  
  72.     while(scanf("%d%d",&m,&n)!=EOF){  
  73.         printf("最大价值为%d\n",knapsack(m,n));  
  74.         trackSolution(m, n);  
  75.     }  
  76.     return 0;  
  77. }  

完全背包问题C++实现

[cpp] view plaincopy
  1. /*任务:计算完全背包问题的最大价值 
  2. Sample Input 
  3. 10 4 
  4. 2 1 
  5. 3 3 
  6. 4 5 
  7. 1 9 
  8. Sample Output 
  9. 90 
  10. 0 0 0 10 
  11. */  
  12. #include<stdio.h>  
  13. #include<string.h>  
  14. int c[20][1000];//c[k][y]为只允许装前k种物品,背包总重量不超过y的最大价值  
  15. int inumber[21][1000];//inumber[k][u]为只允许装前K种物品,h背包总重量不超过y时得到最大价值时使用的背包的最大标号  
  16. int w[21],p[21];  
  17. int knapsack(int m,int n)  
  18. {  
  19.     int i,j;  
  20.     for(i=1;i<n+1;i++)  
  21.         scanf("%d%d",&w[i],&p[i]);  
  22.     memset(c,0,sizeof(c));  
  23.     memset(inumber,0,sizeof(inumber));  
  24.     for(j=1;j<m+1;j++){  
  25.         c[1][j]=j/w[1]*p[1];  
  26.     }  
  27.     for(i=1;i<n+1;i++){  
  28.         for(j=1;j<m+1;j++){  
  29.             if(j >= w[i]){  
  30.                 if(p[i]+c[i][j-w[i]]>=c[i-1][j]){//和0-1背包相比只是将c[i-1][j-w[i]]写成了c[i][j-w[i]],因为完全背包问题中每件物品有无限个  
  31.                     c[i][j]=p[i]+c[i][j-w[i]];  
  32.                     inumber[i][j]=i;  
  33.                 }     
  34.                 else{  
  35.                     c[i][j]=c[i-1][j];  
  36.                     inumber[i][j]=inumber[i-1][j];   
  37.                 }  
  38.             }  
  39.             else{  
  40.                 c[i][j]=c[i-1][j];  
  41.                 inumber[i][j]=inumber[i-1][j];   
  42.             }  
  43.         }  
  44.     }  
  45.     return(c[n][m]);                       
  46. }  
  47.   
  48. void trackSolution(int m, int n){  
  49.     int x[21];  
  50.     int y = m;  
  51.     int j = n;  
  52.     memset(x, 0, sizeof(x));  
  53.     while(true){  
  54.         j = inumber[j][y];  
  55.         x[j] = 1;  
  56.         y = y - w[j];  
  57.         while(inumber[j][y] == j){  
  58.             y = y - w[j];  
  59.             x[j]++;  
  60.         }  
  61.         if(!inumber[j][y]) break;  
  62.     }  
  63.     printf("最大价值方案中各个物品的个数为(物品标号从1到n):");  
  64.     for(j = 1; j <= n; j++){  
  65.         printf("%d ", x[j]);  
  66.     }  
  67.     printf("\n");  
  68. }  
  69. int main()  
  70. {  
  71.     int m,n;  
  72.     while(scanf("%d%d",&m,&n)!=EOF){  
  73.         printf("最大价值为%d\n",knapsack(m,n));  
  74.         trackSolution(m, n);  
  75.     }  
  76.     return 0;  
  77. }  

0 0
原创粉丝点击