背包系列已更新

一,(01背包,填满背包)

二,(多重背包)

三,(完全背包)

目录

一,01背包(对于一个物品,你要么全拿,要么不拿)

核心dp方程,dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i]]+b[i])  //i为物品数量,j为空间,a[i]为物品占的空间,b[i]为物品价

1, 二维 ac代码

2,优化压缩一维

二,填满背包(只有这个拿了且能把背包空间装满才拿,不然不拿)

1,二维基础

AC代码

2,一维优化(还是一样的道理,简洁又高效)


一,01背包(对于一个物品,你要么全拿,要么不拿)

核心dp方程,dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i]]+b[i])  //i为物品数量,j为空间,a[i]为物品占的空间,b[i]为物品价

for (int i = 1; i <= n; ++i)for (int j = 0; j <= m; ++j){if (j - a[i] >= 0)dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - a[i]] + b[i]);else dp[i][j] = dp[i - 1][j];  //当然,写上述方程需要你先装得下物品i再说,不行只能继承前面}

dp思想是我拿i个,那我只需要假设前面i-1个已经拿了最优,则拿第i个时,我判断,如果拿第i个,那么前面剩余空间为[j-a[i]],那么dp[i-1][j-a[i]]+b[i]就是前i-1个,[j-a[i]]的空间加上第i个的价值比上我不拿第i个的价值,取大值

明确后我们就可以从头写到尾

1, 二维 ac代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>using namespace std;
#define ll long longconst int N = 1100;//数组放外面默认初始为0
int dp[N][N];
int a[N];  //消耗猫粮
int b[N];//获得豆子int main() {int m, n;  //m为猫粮(即我的空间,n为房间,即物品数量while (cin >> m >> n&&(n!=-1||m!=-1)) {memset(dp, 0, sizeof(dp));for (int i = 1; i <= n; ++i)cin >> b[i] >> a[i];for (int i = 1; i <= n; ++i)for (int j = 0; j <= m; ++j)//表示选择第i个物品时,此时有j空间{     //j初始化为0,因为可能0空间背包也能装大小(占0空间大小的物品(滑稽))if (j - a[i] >= 0)dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - a[i]] + b[i]);else dp[i][j] = dp[i - 1][j];  //当然,写上述方程需要你先装得下物品i再说,不行只能继承前面}cout << dp[n][m] << endl;}return 0;
}

2,优化压缩一维

显然,当我N取1e6或者更大时,二维数组就爆了,而且,我们发现dp转移方程,都是i-1是不是有点多余,于是我们可以选择去除这个i,只保留j就好

核心

 for (int i = 1; i <= n; ++i)for (int j = m; j>=a[i]; --j) {//这里i放前面,j放后面,且j从大循环到小,保证一个i只拿一次,j从大到小,就保证本次j空间存入i,后面大空间不会再存一次(因为我从大空间到小空间),导致重复使用dp[j] = max(dp[j], dp[j - a[i]] + b[i]);           //j取到a[i] ,一是防止前面什么0空间还能拿的情况出现,二是你j小于a[i]了,也还是dp[j],不会更新,不用去浪费时间循环        //这样我dp[j]更新的都是上一组拿i-1个的,不会重复
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>using namespace std;
#define ll long longconst int N = 1100;//数组放外面默认初始为0
int dp[N];
int a[N];  //消耗猫粮
int b[N];//获得豆子int main() {int m, n;  //m为猫粮(即我的空间,n为房间,即物品数量while (cin >> m >> n&&(n!=-1||m!=-1)) {memset(dp, 0, sizeof(dp));for (int i = 1; i <= n; ++i)cin >> b[i] >> a[i];for (int i = 1; i <= n; ++i)for (int j = m; j>=a[i]; --j) {//这里i放前面,j放后面,且j从大循环到小,保证一个i只拿一次,j从大到小,就保证本次j空间存入i,后面大空间不会再存一次(因为我从大空间到小空间),导致重复使用dp[j] = max(dp[j], dp[j - a[i]] + b[i]);           //j取到a[i] ,一是防止前面什么0空间还能拿的情况出现,二是你j小于a[i]了,也还是dp[j],不会更新,不用去浪费时间循环        //这样我dp[j]更新的都是上一组拿i-1个的,不会重复}cout << dp[m] << endl;}return 0;
}

二,填满背包(只有这个拿了且能把背包空间装满才拿,不然不拿)

其实跟01背包没有很大区别,我们在dp转移加一个判断就好了,只要前面的dp[i-1][j]小于0,我就不装物品,因为他不是填满的。只有满的我才装

1,二维基础

AC代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>using namespace std;
#define ll long longconst int N = 1100;//数组放外面默认初始为0
int dp[N][N];
int a[N];  //消耗猫粮
int b[N];//获得豆子int main() {int m, n;  //m为猫粮(即我的空间,n为房间,即物品数量while (cin >> m >> n&&(n!=-1||m!=-1)) {memset(dp, -1, sizeof(dp));   //初始值赋值-1,设定他们没有填满dp[0][0] = 0;//当然,0空间的背包肯定是满的,这样就作为起点for (int i = 1; i <= n; ++i)cin >> b[i] >> a[i];for (int i = 1; i <= n; ++i)for (int j = 0; j <= m; ++j) {if (j - a[i] >= 0) {//首先空间要装的下,这是前提,否则你越负数空间访问得到的就不是正确答案了if (dp[i - 1][j - a[i]] >= 0)dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - a[i]] + b[i]);//只有前面dp为0或者大于0,我才赋值else dp[i][j] = dp[i - 1][j];//这里补一句,是因为,可能进了第一个if,但是第二个if又进不去,然后进来第一个if后面的else就不会去了,导致没有继承前面的dp[i][j] = dp[i - 1][j];}                          //所以写二维真的浪费空间,浪费时间,浪费脑力,好好学一维吧else dp[i][j] = dp[i - 1][j];}cout << dp[n][m] << endl;//如果没有被赋值到,那么他初始化就是-1,有就是答案}return 0;
}

2,一维优化(还是一样的道理,简洁又高效)

#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>using namespace std;
#define ll long longconst int N = 1100;//数组放外面默认初始为0
int dp[N];
int a[N];  //消耗猫粮
int b[N];//获得豆子int main() {int m, n;  //m为猫粮(即我的空间,n为房间,即物品数量while (cin >> m >> n&&(n!=-1||m!=-1)) {memset(dp, -1, sizeof(dp));   //初始值赋值-1,设定他们没有填满dp[0] = 0;//当然,0空间的背包肯定是满的,这样就作为起点for (int i = 1; i <= n; ++i)cin >> b[i] >> a[i];for (int i = 1; i <= n; ++i)for (int j = m; j >= a[i]; --j) {   //j的范围大于等于a[i]就好,因为你小了肯定不用更新(一维又不需要继承前面i-1的数据)if (dp[j - a[i]] >= 0)dp[j] = max(dp[j], dp[j - a[i]] + b[i]);//可以就更新,不行不用管}cout << dp[m] << endl;}return 0;
}

背包问题_(DP经典),一,(01背包,填满背包)相关推荐

  1. dp(十一)填满背包方案数

    目录 LintCode 炼码物品大小不重复的填满背包的方案数 LintCode 炼码 物品大小存在重复情况 LintCode 炼码不重复的组合个数 完全背包_牛客题霸_牛客网 LintCode 炼码物 ...

  2. python 回溯法 01背包问题_回溯法解决01背包问题

    回溯法是一个既带有系统性又带有跳跃性的搜索算法. 它在包含问题的所有解的解空间树中按照 深度优先的策略, 从根节点出发搜索解空间树. 算法搜索至解空间树的任一节点时, 总是先判断 该节点是否肯定不包含 ...

  3. 代码随想录算法训练营第四十三天 | 填满背包有几种方法、背包有两个维度

    1049.最后一块石头的重量II 文档讲解:代码随想录 (programmercarl.com) 视频讲解:动态规划之背包问题,这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II ...

  4. python完全背包最优_python 完全背包问题_遗传算法Python实战 009.背包问题

    原标题:遗传算法Python实战 009.背包问题 写在前面的话 以下部分内容,来自百度 背包问题(Knapsack problem)是一种组合优化的NP完全问题.问题可以描述为:给定一组物品,每种物 ...

  5. 数据结构背包问题c语言思路,C语言学习趣事_数据结构_经典命题_1_背包问题_分析_1...

    /*1.问题描述 假设有一个能装入总体积为T的背包和n件体积分别为w1,w2,-wn的物品, 能否从n件物品中挑选若干件恰好装满背包,即使w1+w2+-+wm=T, 要求找出所有满足上述条件的解. 例 ...

  6. 背包九讲系列1——01背包、完全背包、多重背包

    我在进行一些互联网公司的技术笔试的时候,对于我来说最大的难题莫过于最后的那几道编程题了,这对算法和数据结构有一定程度上的要求,而"动态规划"又是编程题中经常出现的算法类型,并且对于 ...

  7. 01背包,完全背包,多重背包的个人总结

    大一刚接触背包问题的时候就觉得绕.那时候真的是一点代码基础都没有强行去理解.每次都是以失败告终,一直到大二都还不会写背包问题. 后来某次模拟赛之后碰到了背包问题,觉得这个还是挺简单的,终于是下定决心准 ...

  8. 背包详解:完全背包与多重背包

    目录 完全背包 优化一:输入优化 优化二:二进制 优化三:重复放入的 01 背包 多重背包 总结 完全背包 有一个大小为 m 的背包,有 N 种物体,每种物品的价值为 Vi, 大小为 Ai, 并且每种 ...

  9. java01背包问题算法_经典动态规划--01背包问题

    背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3.物品a1重量为3kg,价值为4:物品a2重量为4kg,价值为5:物品a3重量为5kg,价值为6.将哪些物品放入背包 ...

最新文章

  1. CentOS 6.5 下安装 Redis 2.8.7
  2. [转]Entity Framework4.0 (七) EF4的存储过程
  3. stm32之端口复用和重映射
  4. C#设置标记方法等为否决的不可用
  5. P3279-[SCOI2013]密码【Manacher】
  6. python计算球坐标系的积分_python – n球面坐标系到笛卡尔坐标系
  7. Java8学习笔记(七)--Collectors
  8. 【CodeSnippet】Gradle
  9. python aop编程_学习笔记: AOP面向切面编程和C#多种实现
  10. Windows和linux(ubuntu)互传文件简便快捷的方法
  11. Redhat 5.4 Oracle 10g RAC 删除节点
  12. Stanford CS224N: PyTorch Tutorial (Winter ‘21) —— 斯坦福CS224N PyTorch教程 (第三部分)
  13. Linux服务器多线程编程
  14. (hightopo)学习笔记(1)
  15. 单交换机配置vlan
  16. nginx负载接口与宕机切换
  17. 数据结构(C语言)-串子系统(实验)
  18. HTML5期末大作业:动漫网站设计——迪斯尼公主(6个页面) HTML+CSS+JavaScript 动漫网页HTML代码 学生网页课程设计期末作业下载 动漫大学生网页设计制作成
  19. dlink中设置端口映射图文讲解(解决电驴tcp链接测试失败问题)
  20. wxpython入门(1)

热门文章

  1. 简洁,简单,再简化...
  2. 如何续费iOS开发者账号 - 详细步骤
  3. mounted钩子函数_vue中created钩子函数与mounted钩子函数的使用区别
  4. 第十四章第五节:Java集合框架之优先级队列PriorityQueue(堆)
  5. 外键不兼容问题( in foreign key constraint are incompatible)
  6. 数据库第一天 TAT
  7. UE4 版本迭代、资源热更、pak更新方案
  8. 备战秋招,LeetCode算法大总结,啃下这块硬骨头
  9. android chrome 工具栏,安卓chrome://flags中值得调整的的选项
  10. JS 实现数字滚动变化效果