转自:http://blog.csdn.net/tjyyyangyi/article/details/7929665

0-1背包问题

参考:

http://blog.csdn.net/liwenjia1981/article/details/5725579

http://blog.csdn.net/dapengbusi/article/details/7463968

动态规划解法

借个图 助于理解

从背包容量为0开始,1号物品先试,0,1,2,的容量都不能放.所以置0,背包容量为3则里面放4.这样,这一排背包容量为 4,5,6,....10的时候,最佳方案都是放4.假如1号物品放入背包.则再看2号物品.当背包容量为3的时候,最佳方案还是上一排的最价方案c为 4.而背包容量为5的时候,则最佳方案为自己的重量5.背包容量为7的时候,很显然是5加上一个值了。加谁??很显然是7-4=3的时候.上一排 c3的最佳方案是4.所以。总的最佳方案是5+4为9.这样.一排一排推下去。最右下放的数据就是最大的价值了。(注意第3排的背包容量为7的时候,最佳 方案不是本身的6.而是上一排的9.说明这时候3号物品没有被选.选的是1,2号物品.所以得9.)

  1. #include<stdio.h>
  2. int f[10][100];
  3. //构造最优矩阵
  4. void package0_1(int *w,int *v,int n,int c)
  5. {
  6. int i,j;
  7. //初始化矩阵
  8. for(i=1;i<=n;i++)
  9. f[i][0] = 0;
  10. for(j=1;j<=c;j++)
  11. f[0][j] = 0;
  12. for(i=1;i<=n;i++)
  13. {
  14. for(j=1;j<=c;j++)
  15. {
  16. //当容量够放入第i个物品,并且放入之后的价值要比不放大
  17. if(w[i] <= j && f[i-1][j-w[i]] + v[i] > f[i-1][j])
  18. {
  19. f[i][j] = f[i-1][j-w[i]] + v[i];
  20. }else
  21. f[i][j] = f[i-1][j];
  22. }
  23. }
  24. printf("最大价值: %d \n",f[n][c]);
  25. }
  26. //构造最优解
  27. void getResult(int n,int c,int *res,int *v,int *w)
  28. {
  29. int i,j;
  30. j = c;
  31. for(i=n;i>=1;i--)
  32. {
  33. if(f[i][j] != f[i-1][j])
  34. {
  35. res[i] = 1;
  36. j = j - w[i];
  37. }
  38. }
  39. }
  40. void main()
  41. {
  42. int w[6] = {0,2,2,6,5,4};//每个物品的重量
  43. int v[6] = {0,6,3,5,4,6};//每个物品的价值
  44. int res[5] = {0,0,0,0,0};
  45. int n = 5; //物品的个数
  46. int c = 10; //背包能容的重量
  47. int i,j;
  48. package0_1(w,v,n,c);
  49. for(i=0;i<=n;i++)
  50. {
  51. for(j=0;j<=c;j++)
  52. printf("%2d ",f[i][j]);
  53. printf("\n");
  54. }
  55. getResult(n,c,res,v,w);
  56. printf("放入背包的物品为: \n");
  57. for(i=1;i<=n;i++)
  58. if(res[i] == 1)
  59. printf("%d  ",i);
  60. }

0-1背包的递归解法

  1. #include<stdio.h>
  2. int maxNum[6];  //存放最优解的编号
  3. int maxValue=0; //存放最大价值
  4. int w[6] = {0,2,2,6,5,4};//每个物品的重量,第一个为0,方便角标对应
  5. int v[6] = {0,6,3,5,4,6};//每个物品的价值,第一个为0,方便角标对应
  6. int num = 5; //物品的个数
  7. int cap = 10; //背包能容的重量
  8. void package01(int *flag,int n,int c,int nowValue)
  9. {
  10. int i;
  11. if(n == 0 || c == 0)
  12. {
  13. if(nowValue > maxValue)
  14. {
  15. for(i=0;i<6;i++)
  16. maxNum[i] = flag[i];
  17. maxValue = nowValue;
  18. }
  19. return;
  20. }
  21. if(c >= w[n])
  22. {
  23. flag[n] = 1;
  24. package01(flag, n-1, c-w[n], nowValue+v[n]);
  25. }
  26. flag[n] = 0;
  27. package01(flag, n-1, c, nowValue);
  28. }
  29. void main()
  30. {
  31. int flag[6] = {0,0,0,0,0,0};
  32. int i;
  33. package01(flag,num,cap,0);
  34. for(i=1;i<=num;i++)
  35. maxNum[i] == 1 ? printf("第%d号货物装了包中  \n",i) : 0;
  36. printf("最大价值为:%d  \n",maxValue);
  37. }

完全背包问题

与0-1背包问题区别在每个物品有无限多个。

  1. #include<stdio.h>
  2. int f[10][100];
  3. //构造最优矩阵
  4. void package0_1(int *w,int *v,int n,int c)
  5. {
  6. int i,j,k;
  7. //初始化矩阵
  8. for(i=1;i<=n;i++)
  9. f[i][0] = 0;
  10. for(j=1;j<=c;j++)
  11. f[0][j] = 0;
  12. for(i=1;i<=n;i++)
  13. {
  14. for(j=1;j<=c;j++)
  15. {
  16. //当容量够放入k个第i个物品,并且放入之后的价值要比不放大
  17. k = j/w[i];
  18. if( k>0 && (f[i-1][j- k * w[i]] +  k * v[i] > f[i-1][j]))
  19. {
  20. f[i][j] = f[i-1][j- k * w[i]] +  k * v[i] ;
  21. }else
  22. f[i][j] = f[i-1][j];
  23. }
  24. }
  25. printf("最大价值: %d \n",f[n][c]);
  26. }
  27. //构造最优解
  28. void getResult(int n,int c,int *res,int *v,int *w)
  29. {
  30. int i,j;
  31. j = c;
  32. for(i=n;i>=1;i--)
  33. {
  34. while(f[i][j] > f[i-1][j])
  35. {
  36. res[i] ++;
  37. j = j - w[i];
  38. }
  39. }
  40. }
  41. void main()
  42. {
  43. int w[6] = {0,4,6,6,3,6};//每个物品的重量
  44. int v[6] = {0,1,1,1,2,1};//每个物品的价值
  45. int res[5] = {0,0,0,0,0};
  46. int n = 5; //物品的个数
  47. int c = 10; //背包能容的重量
  48. int i,j;
  49. package0_1(w,v,n,c);
  50. for(i=0;i<=n;i++)
  51. {
  52. for(j=0;j<=c;j++)
  53. printf("%2d ",f[i][j]);
  54. printf("\n");
  55. }
  56. getResult(n,c,res,v,w);
  57. printf("放入背包的物品为: \n");
  58. for(i=1;i<=n;i++)
  59. if(res[i] >= 1)
  60. printf("放入了第%d号物品%d个\n  ",i,res[i]);
  61. }

部分背包问题

与0-1背包的区别:装入的可以不是整个装入,理解为“装沙”。其余要求一样。

用贪心法求解

  1. #include<stdio.h>
  2. void package_part(int *w,int *v,double *p,int n,int c,int *flag)
  3. {
  4. int i,j,temp;
  5. double tempD,totalValue = 0.0;
  6. //计算单价
  7. for(i=0;i<n;i++)
  8. {
  9. p[i] = (double)v[i] / (double)w[i];
  10. flag[i] = i;
  11. }
  12. //根据单价排序,flag数组保存物品的下标
  13. for(i=0;i<n;i++)
  14. {
  15. for(j=n-1;j>i;j--)
  16. {
  17. if(p[j] > p[j-1])
  18. {
  19. temp = flag[j];
  20. flag[j] = flag[j-1];
  21. flag[j-1] = temp;
  22. tempD = p[j];
  23. p[j] = p[j-1];
  24. p[j-1] = tempD;
  25. }
  26. }
  27. }
  28. //贪心法得出应该装入的物品
  29. for(i=0;i<n;i++)
  30. {
  31. if(c >= w[flag[i]])
  32. {
  33. totalValue += v[flag[i]];
  34. c -= w[flag[i]];
  35. printf("第%d号物品整个放入\n",flag[i]);
  36. }else
  37. {
  38. totalValue += p[flag[i]] * (double)c / (double) w[flag[i]];
  39. printf("第%d号物品放入了%f\n",flag[i],(double)c / (double) w[flag[i]]);
  40. break;
  41. }
  42. }
  43. printf("总价值为:%f",totalValue);
  44. }
  45. void main()
  46. {
  47. int w[5] = {4,6,6,3,6};//每个物品的重量
  48. int v[5] = {1,1,1,2,1};//每个物品的价值
  49. double p[5] = {0,0,0,0,0};//每个物品的单位价值
  50. int flag[5]; //用于排序
  51. int n = 5; //物品的个数
  52. int c = 10; //背包能容的重量
  53. package_part(w,v,p,n,c,flag);
  54. }

最新文章

  1. js获取可视区域高度
  2. JVM之GI收集器
  3. PHP清理跨站XSS xss_clean 函数 整理自codeigniter Security
  4. Visual Studio 拓展插件——Image Optimizer
  5. js模拟快捷键操作表单
  6. RAC 数据库的启动与关闭
  7. 隐藏tabBar页面跳转后会再布局一次,
  8. 洛谷 P1273 有线电视网
  9. 蝇量模式(Flyweight Pattern)
  10. php四种基础排序算法的运行时间比较
  11. HDU 2985 Another lottery(坑题)
  12. VS2010打不开VS2012 .NET MVC 工程,及打开后部分模块加载不正确的解决办法
  13. 网站运维工具使用iis日志分析工具分析iis日志(iis日志的配置)
  14. PHP发送邮件功能--ThinkPHP3.2.3
  15. 归档(NSKeyedArchiver)的使用
  16. div中的内容超过容器宽度的问题
  17. spring boot新建项目启动报:Unregistering JMX-exposed beans on shutdown
  18. Python入门(白银篇)
  19. spring学习(五) ———— 整合web项目(SSM)
  20. P3587 [POI2015]POD

热门文章

  1. vue.js学习与实战笔记(2)
  2. 基于Netty4手把手实现一个带注册中心和注解的Dubbo框架
  3. [loj2245]魔法森林
  4. [noi253]A
  5. [GYCTF2020]Easyphp
  6. html图片动态增加文字
  7. Stream流的使用
  8. Python之用型号构成一个三角形代码
  9. you crash I crash
  10. C++栈溢出