自打师哥布置了背包问题的作业之后,虽然看了不少次,但每次不是因为时间太紧,要不就是太难了老想逃避,一直没解决这个问题。终于借着学校运动会,抓紧时间看了看C 语言背包问题的实现,动态规划还是太难,只好先从 C 入手来解决理解一下。当时师哥提到这个背包问题的时候,我并没理解这个问题的意思,师哥给的数据是:一个容量为 10 的背包,四个物品重量分别为 5 , 4 , 6 , 3 ;价值为 10 , 40 , 30 , 5 ;求这个背包可容纳物品的最大价值?具体我当时的心理活动现在已经忘了,我只记得当时的确是理解错了,没明白什么意思。后来又去网上百度,百度的解释如下:

背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。相似问题经常出现在商业、组合数学,计算复杂性理论、密码学和应用数学等领域中。也可以将背包问题描述为决定性问题,即在总重量不超过W的前提下,总价值是否能达到V?它是在1978年由Merkel和Hellman提出的。

背包问题已经研究了一个多世纪,早期的作品可追溯到1897年 数学家托比亚斯·丹齐格(Tobias Dantzig,1884-1956)的早期作品  ,并指的是包装你最有价值或有用的物品而不会超载你的行李的常见问题。

背包问题的应用:

1998年石溪布鲁克算法库发现在75个算法问题中,背包问题是第18个最受欢迎,第4个最需要解决的问题。各种领域的决策问题都会出现,如寻找最少的浪费来削减原材料,选择投资和投资组合,选择资产支持资产证券化,和生成密钥为和其他背包密码系统。

背包问题的定义:

我们有n种物品,物品j的重量为wj,价格为pj。

我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为W。

如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。

如果不限定每种物品的数量,则问题称为无界背包问题。

各类复杂的背包问题总可以变换为简单的0-1背包问题进行求解。

记得刚读完百科的解释后,我想着可不可以把每个物品是否要都考虑一遍,然后全排列,看看哪种情况是正确的,后来这种做法直接被否定了,因为早考虑的情况太多,当物品非常多的时候,有可能就无法进行了。后来听同学说,考虑一件物品的去留,当时我是怀疑的,因为当从一件开始考虑时我认为这件物品和其他物品的关联就断了,也就是说你不能考虑整体的,可当真正开始处理的时候才明白,从一个物品开始,一个个考虑,是背包问题C语言解决的思路。

#include"stdio.h"
#define MAX 20int Min(int x, int y)
{
return x <= y ? x : y;
}int Max(int x, int y)
{
return x >= y ? x : y;
}void TraceBack(int (*middle)[MAX], int *weight, int column, int length, int *x)
{
int i;
for(i = 1; i < length; i++)
if(middle[i][column] == middle[i + 1][column])
x[i] = 0;
else
{
x[i] = 1;
column -= weight[i];
}
x[length] = (middle[length][column] ? 1 : 0);
}void Knapsack(int *value, int *weight, int column, int length, int (*middle)[MAX])
{
int i, j, jMax = Min(weight[length] - 1, column);
for(j = 0; j <= jMax; j++)//从最后一个开始观察,因为最后一个代码没有前面值,所以需要单独写middle[length][j] = 0;
for(j = weight[length]; j <= column; j++)
middle[length][j] = value[length];
for(i = length - 1; i > 1; i--)//中间的代码一个一个单独敲
{
jMax = Min(weight[i] - 1, column);
for(j = 0; j <= jMax; j++)
middle[i][j] = middle[i + 1][j];
for(j = weight[i]; j <= column; j++)
middle[i][j] = Max(middle[i + 1][j], middle[i + 1][j - weight[i]] + value[i]);
}
middle[1][column] = middle[2][column];//最后的一组可以不考虑前面的情况,直接考虑最后他自己是否需要加入就可以
if(column >= weight[1])
middle[1][column] = Max(middle[1][column], middle[2][column - weight[1]] + value[1]);
}int main(void)
{
int i, length, column, count = 0, wj[MAX], pj[MAX], x[MAX] = {0}, middle[MAX][MAX] = {0};
printf("请输入背包总容量:\n");
scanf("%d", &column);
printf("请输入物品个数:\n");
scanf("%d", &length);
/*if(length < 1)
{
printf("输入错误!!!\n");
return;
}//判断*/
for(i = 1; i <= length; i++)
{
printf("请输入第%d个物品的重量及价值:\n", i);
scanf("%d %d", wj + i, pj + i);//为什么不在0开始
}
Knapsack(value, wj, column, length, middle);
TraceBack(middle, wj, column, length, x);
printf("Result:\n");
for(i = 1; i <= length; i++)
if(x[i])
printf("Number: %d, ", i);
printf("\n");
}

背包问题的C语言实现相关推荐

  1. 背包问题C/C++语言

    基于C语言的背包问题(语言只是工具,重要的是思想) 在解决问题之前,为描述方便,首先定义一些变量:Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i ...

  2. 0-1背包问题 动态规划c语言,详解动态规划01背包问题--JavaScript实现

    一开始在接触动态规划的时候,可能会云里雾里,似乎能理解思路,但是又无法准确地表述或者把代码写出来.本篇将一步一步通过作图的方式帮助初次接触动态规划的同学来理解问题.这一篇将以经典的 01背包 问题为例 ...

  3. 0-1背包问题(C语言)

    任务描述 本关任务:编写一个能求解0-1背包问题的程序. 相关知识 为了完成本关任务,你需要掌握如何编写动态规划程序 有一个背包,能装载的总重量为C<300, 有 n<100个物体,每个物 ...

  4. 回溯算法背包问题迭代c语言,回溯法解决0_1背包问题(迭代和递归)

    问题:0/1背包问题 例子:weight数组代表物品重量,value数组代表物品价值,M代表背包容量.背包是按单位价值递减的顺序排列的,即value[i]/weight[i]>value[i-1 ...

  5. 动态规划之背包问题(C语言)

    动态规划 动态规划(英语:Dynamic programming,简称DP)是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划常常适用于有重叠子问题和最优子结构性质的问题 动 ...

  6. 贪心算法 背包问题代码 c语言,用贪心算法求解普通背包问题的C++代码

    用贪心算法求解普通背包问题的C++代码 2019年3月6日 125次阅读 来源: 贪心算法 #include #define  M  100 void display(int &n,doubl ...

  7. 让你轻松搞懂0-1背包问题(动态规划 C语言版)

    题目描述 有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 举一个例子: 有一个小偷他有一个容量为8的背包 物体的体积和价值如下所示: 物体编号 物体 ...

  8. 遗传算法之01背包问题 (C语言实现)

    参数说明 n:物品个数 m:种群大小 W:背包容量 其中 a[i] 存储的物品信息 ,g[i]存储基因信息. maxn :物品数的最大值 maxm :种群数的最大值 注意事项 m 最好是 n 的10倍 ...

  9. 粒子群算法之01背包问题(C语言实现)

    参数说明 Vi(t+1)=ωVi(t)+c1r1(pbesti−Xi(t))+c2r2(gbest−Xi(t)) 根据粒子群算法速度迭代公式: w:惯性因子 c1,c2:学习率 r1,r2:[0,1] ...

最新文章

  1. VC回调函数定义和使用
  2. 大量POI点展示的一种解决方案
  3. 使用摄像头运行ORB SLAM2---使用视频运行ORB-SLAM2
  4. 【深度学习】用Pytorch给你的母校做一个样式迁移吧!
  5. 2015年第六届蓝桥杯 - 省赛 - C/C++大学A组 - A. 方程整数解
  6. 字符数据类型转换代码
  7. 基本类型和字符串互相转换
  8. Introduce Foreign Method(引入外加函数)
  9. MySQL-01-linux安装MySQL的两种方式及其遇到的问题
  10. Solr分析器IK-analyzer配置及错误java.lang.AbstractMethodError解决
  11. Jenkins-SCM
  12. 情侣博客源码php,wordpress如何搭建简单的情侣博客
  13. java动态字段排序_Java利用Stream来实现多字段排序功能
  14. 分数加减乘除混合运算带答案_分数加减乘除混合运算专项训练
  15. 2018DeeCamp面试题目
  16. windows 2003 directx 3D加速 开启
  17. SAP ERP FI(Financial Accounting)财务会计--BW方向--初级--1
  18. Elasticsearch模块——CRUD
  19. java socket 卡住_Java socket通讯实现过程及问题解决
  20. html怎么设置一个表格的宽度一样吗,html表格单元格大小 怎样在html中设置所有表格大小一样...

热门文章

  1. 用python实现线性回归算法
  2. 头条--黑马头条_day08
  3. js中选择排序的实现
  4. 提升领导力的 7 种方法
  5. 矩阵论复习笔记-华中科技大学
  6. html间隔大的虚线,html如何增加虚线边框之间的间距_html_开发99编程知识库
  7. Docker安装默认存储路径修改与镜像恢复
  8. SQL语句 - 跟踪PO对应的PR、Receipt、invoice信息
  9. spark sql任务性能优化(基础)
  10. odps之sql性能优化