直接上题

先说朴素的想法
我认为动态规划的题目,都是要用到每一步的答案,将每一步的答案作为解题的线索
那么题目让我们考虑有四个物品,分别告诉了你四个物品的体积和价值,且每个物品的数量只有一个
让你利用这些条件找出一种物品序列,使其放入容量为5的背包后的价值最大
那我直接搬出朴素的解法
就是创建一个二维数组f[ i ][ j ]
i表示物品的编号,j表示背包的容量,每一个f的值就代表往容量为j的背包中放入1~i号物品所能达到的最大价值
那么创建好这个二维数组之后,就要开始对它进行赋值
赋值的顺序是从左到右,从上到下
赋值的方法就是比如你现在准备给f[1][2]赋值
就是往容量为2背包中放编号为1的物品最大能达到的价值是多少
那么你首先就要考虑1的体积是否要比2大,显然如果比2还大,那么就放不下,f[1][2]的值就为0,如果放得下,那么就是往里放一个1号物品,此时背包总价值为2,且因为1号物品已经用完,没有物品可放,所以得到容量为2背包中放编号为1的物品最大能达到的价值就是2,将
f[1][2]的值置为2即可
那么这样一来,通过这样的方法我们就能将第一行中的所有空位全部赋值成功
也就是说,我们得到了容量从0~5背包放入编号为1的物品分别所能达到的最大价值
接下来,从第二行继续
假设我们现在想赋值的是f[2][2],我们发现此时背包容量可以放入物品2,那么问题就来了,我们到底是放入物品2使得背包的价值最大,还是不放入物品2背包的价值最大呢?
这里我们注意一个点,如果我们此时选择放入物品2,那么我们该如何使得放入物品2之后的背包价值最大呢?
根据我们之前说的,我们每一个f[i][j],意思都是当前容量下放0~i号物品所能达到的最大价值,那么也就是说,我们放入物品2之后,背包的容量此时应该变为减去物品2的体积,我们用
f[2-1][j-物品2的体积]就可以表示在放入物品2之后剩余背包的所能达到的最大价值了,那么放入物品2所能达到的最大价值就是——物品2的价值+f[2-1][j-物品2的体积]([2-1]是因为物品2只有一个,已经被用掉了,接下来只剩下物品1了)
这样一来,我们用 物品2的价值+f[2-1][j-物品2的体积] 与不放入物品2背包的最大价值——也就是f[2-1][j]相比,两者谁更大,f[2][2]就等于谁
那么朴素思想差不多就这样,最大的价值显然就是二维数组的最左下角的一项f[n][m]

#include<stdio.h>
struct bag{int v,w;
}number[1005];
int main()
{/*创建一个二维数组,这个二维数组的横坐标用来表示物品编号,纵坐标用来表示背包容量*/int i,j;scanf("%d%d",&i,&j);int a[i+1][j+1];int b[i+1];number[0].v = number[0].w = 0;for(int i_ = 1;i_ < i+1;i_++)scanf("%d%d",&number[i_].v,&number[i_].w);for(int i_ = 0;i_ < i+1;i_++){for(int j_ = 0;j_ < j+1;j_++)a[i_][j_] = 0;}/*对数组进行赋值,从左至右,从上至下*/for(int i_ = 0;i_ < i+1;i_++){for(int j_ = 0;j_ < j+1;j_++){if(i_ == 0||j_ == 0)a[i_][j_] = 0;else if(number[i_].v > j_){//当前装入物品装不下 a[i_][j_] = a[i_-1][j_];}else{//装得下 if((number[i_].w+a[i_-1][j_-number[i_].v])>(a[i_-1][j_]))a[i_][j_] = number[i_].w+a[i_-1][j_-number[i_].v];elsea[i_][j_] = a[i_-1][j_];}}}printf("%d",a[i][j]);
}

说完朴素法,我们有没有方法对其进行优化呢?
显然是有的,我们可以将二维数组压缩成一维数组
为什么可以这样,因为我们发现
在对二维数组进行赋值的时候,我们如果不放入i物品,那么空就等于当前背包容量下放0 ~ i-1号物品的最大价值,如果我们决定放i物品,那么空就等于背包容量减去i后放0~i-1号物品的最大价值+当前物品的价值
即我们进行赋值时,压根就没有用到当前空的上一排之外的数据,所以我们可以将二维数组设置成一个滚动的一维数组,节省空间

#include<stdio.h>
int value[1000],volume[1000],dp[1000];
int main()
{int n,m,i,j;scanf("%d%d",&n,&m);for(i = 1;i <= n;i++)scanf("%d%d",&volume[i],&value[i]);for(i = 1;i <= n;i++)for(j = m;j >= volume[i];j--){if(dp[j-volume[i]]+value[i] > dp[j])dp[j] = dp[j-volume[i]]+value[i];}printf("%d",dp[m]);
}

注意一下for(j = m;j >= volume[i];j - -)
为什么需要逆序更新滚动数组呢j = m
想一想,因为如果你正序更新,首先如果放不下i物品,那么前面背包容量小于i物品体积的值都为头顶上第i-1行的值,那么一旦背包容量增大到可以装下物品i,判断是否需要更新数值的不等式用到的数据就是你已经更新过的数据(也就是第i行的数据),显然与我们用第i-1行数据的想法相违背
那么如果逆序更新数组,那么用到的就都是第i-1行的数据进行更新判断了
j >= volume[i]
意思就是如果背包容量都装不下i物品,那么数组值就是不放i物品的值(也就是等于第i-1行的值),不需要更新了

01背包的朴素解法及优化(C语言)相关推荐

  1. 背包问题(01背包,完全背包,多重背包(朴素算法二进制优化))

    写在前面:我是一只蒟蒻~~~ 今天我们要讲讲动态规划中~~最最最最最~~~~简单~~的背包问题 1. 首先,我们先介绍一下  01背包 大家先看一下这道01背包的问题   题目   有m件物品和一个容 ...

  2. 01背包及其变种(物品无限背包、恰好装满背包)

    一.01背包问题 01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为C1,C2,-,Cn,与之相对应的价值为W1,W2,-,Wn.求解将那些物品装入背包可使总价值最大. 动态规划: ...

  3. 蓝桥杯 波动数列 01背包

    借鉴自:https://blog.csdn.net/wr132/article/details/43861145 https://blog.csdn.net/linqing360/article/de ...

  4. 动态规划总结(01背包 完全背包 多重背包)

    动态规划总结(01背包 完全背包 多重背包) 一.学习资料 1.UVA DP 入门专题 2.夜深人静写算法(二) - 动态规划 3.算法之动态规划 4.什么是动态规划?动态规划的意义是什么? 5.01 ...

  5. [01背包] 宠物小精灵之收服(01背包+二维费用背包+思维)

    文章目录 0. 前言 1. 01背包裸题 0. 前言 相关: [背包] 背包问题算法模板(模板) 1. 01背包裸题 1022. 宠物小精灵之收服 每个精灵仅被收服一次,故可以考虑 01 背包,是典型 ...

  6. ZCMU 1919: kirito's 星爆气流斩【01背包的二进制优化】

    ZCMU 1919: kirito's 星爆气流斩 Time Limit: 2 Sec  Memory Limit: 128 MB Description 主角kirito是使用世界首款完全潜行游戏& ...

  7. 背包问题,为什么使用倒叙、顺序分别优化01背包和完全背包.

    一.背景 0-1背包与完全背包的唯一的区别在于0-1背包每个物品只能使用一次,但是完全背包可以重复使用. 二.0-1背包空间优化 假设物品编号1~n i号物品重量w[i] i号物品价值v[i] 以下分 ...

  8. 背包模型dp1:01背包,完全背包,多重背包的两大优化的详解

    01背包问题: 状态表示:f[i][j]表示从只从前i个物体里面选,切总体积不超过j的选法的集合状态表示:f[i][j]表示从只从前i个物体里面选,切总体积不超过j的选法的集合状态表示:f[i][j] ...

  9. 【算法】01背包及其优化详解

    [01背包] 一.问题描述: 在NNN个物品,背包容量为CCC的情况下,每个物品的价值为viv_ivi​,重量为wiw_iwi​,每个物品选择装入背包(1)或者选择不装入背包(0).然后选择物品装入背 ...

最新文章

  1. 浅谈大数据中的 2PC、3PC、Paxos、Raft、ZAB
  2. 【大话设计模式】设计模式系统学习大合集
  3. 详解CockroachDB事务处理系统
  4. Java 实例 - 队列(Queue)用法
  5. advanced east_SpriteKit Advanced —如何构建2,5D游戏(第二部分)
  6. 编程的7个主要步骤:
  7. 莱斯大学找到了多被提升3G/4G网络性能的方法
  8. PTA8、列表偶数位置的元素操作 (10 分)
  9. 30轧制过程的计算机控制系统,中厚板轧制过程计算机控制系统结构的研制(1)
  10. php list() ecah(),PHP each()与list()函数
  11. 【AllenNLP入门教程】: 1、基于Allennlp2.4版本的文本分类
  12. usb调试助手_米卓同屏助手 | 刷短视频必备,一键打通“任督二脉”,双端
  13. 因特尔显卡自定义分辨率_事实:在新版本的“英特尔高清图形控制面板”中设置自定义方法...
  14. 企业网站专业性诊断评价
  15. PyramidNet
  16. 洛谷 P4643 [国家集训队]阿狸和桃子的游戏
  17. linux查看网络流量 命令,linux查看流量命令
  18. Android微信App 分享功能调整,Android 微信SDK分享功能(1)
  19. Linux 入门基本操作
  20. iOS_预编译(宏)#if #ifdef #ifndef #elif #else #endif

热门文章

  1. Python实践 - 网络爬虫笔记 - 1、对 URL 的 get 请求
  2. LeetCode-解数独(C++)
  3. opencv去除印章痕迹
  4. 【每日一题】|楼兰图腾(python解法)
  5. 在unity中内置一个查询物流信息功能
  6. 【20岁的时候决定自己的一生】
  7. Zk中组建显示模型mold都有哪些
  8. 云上网站通用解决方案
  9. 2020020801 第007课 裸机开发步骤和gon工具使用
  10. 泰山服务器2280安装系统,用 openEuler 内核构建支持泰山服务器的 Gentoo 系统