1.先放上0-1背包模板

二维数组

for(int i=1;i<=n;i++)//枚举 物品
for(int j=1;j<=V;j++)//枚举体积
//这个位置是可以正序枚举的. qwq
//一维01背包必须倒叙 emmm
//这个没错a emmm
if(j>=c[i])
f[i][j]=max(f[i-1][j],f[i-1][j-c[i]]+w[i]);//状态转移方程.
else f[i][j]=f[i-1][j].

滚动二维数组

    int dp[2][10010];
int row = 0; //滚动
for (int i = 1; i < n; ++i) {
row = 1 - row;
for (int j = 1; j <= i * (i + 1) / 2; ++j) {//这里可以减少枚举
if(j>=c[i])
f[row][j]=max(f[1-row][j],f[1-row][j-c[i]]+w[i]);//状态转移方程.
else f[row][j]=f[1-row][j].
}
}

一维数组(逆序)

for(int i=1;i<=n;i++)//枚举 物品
for(int j=V;j>=c[i];j--)//枚举体积
f[j]=max(f[j],f[j-c[i]]+w[i]);//状态转移方程.

模板题:洛谷:P1048采药

“采药”这道题套模板就行了,从二维到一维优化。

2.顺便再复习记忆化搜索洛谷:P1048采药记忆化搜索做法题解

先想到dfs搜索暴力解题,就是多参数递归,出口记录搜索到的值

再想到记忆化搜索,什么时记忆化搜索?记录每一次dfs答案,免去重复计算,从而起到优化时间复杂度的作用

记忆化搜索记录什么值呢?记录每次搜索结束找到的价值(不一定最大)



如何想到可以用记忆化搜索?

3.蓝桥杯考过的记忆化搜索——2013年C++B组第9题地宫取宝

使用四维数组缓存记录。

4.蓝桥杯考过的0-1背包:2014年C++A组第十题-波动数列

这道题比较难想到0-1背包,选数字对应成拿物品填充背包,dp[i][j]表示用前i个数凑出数字j的方案数,类似题目:我记得有一道选几个数字,凑出数字n。初始化dp[0][0] = 1,第0列都等于1,dp[i~n][0] = 1

5.完全背包

与0-1背包略有不同的是,每种物品有无限多个,可重复选取。

二维数组,三层循环模板

for(int i=1;i<=n;i++)//枚举物品
for(int j=1;j<=V;j++)
for(int k=1;k<=V/c[i];k++)//我们的物品最多只能放多少件.
{
if(k*c[i]<=j)
f[i][j]=max(f[i-1][j],f[i-1][j-k*c[i]]+k*w[i]);
else
f[i][j]=f[i-1][j];
//判断条件与01背包相同.
}

一维数组,两层循环模板(顺序枚举,和0-1背包一维恰好相反)

for(int i=1;i<=n;i++)//枚举物品
for(int j=c[i];j<=V;j++)//枚举体积.注意这里是顺序/
f[j]=max(f[j],f[j-c[i]]+w[i]);//状态转移.

完全背包模板题:P1616 疯狂的采药

6.蓝桥杯考过的完全背包:2017年蓝桥杯-包子凑数

1~100000(比较大的值)

初始化dp[0] = 1

完全背包思想,推出布尔类型的dp数组,最后遍历最后dp数组最后一层为true的个数

整数划分(每个数可以用无限次)——完全背包

#include<bits/stdc++.h>
using namespace std; const int maxn = 100005;
int n;
int dp[maxn]; int main(){
cin>>n;
dp[0] = 1;
for(int i=1;i<=n;i++){//可以用到n
for(int j=i;j<=n;j++){//完全背包 每个数字可以用无限次
dp[j] = dp[j] + dp[j-i];
}
}
cout<<dp[n]<<endl;
return 0;
}

整数划分(每个数只能用一次)——0-1背包

#include<bits/stdc++.h>
using namespace std; const int maxn = 100005;
int n;
int dp[maxn]; int main(){
cin>>n;
dp[0] = 1;
for(int i=1;i<=n-1;i++){//不能用n
for(int j=n;j>=i;j--){//0-1背包 倒序
dp[j] = dp[j] + dp[j-i];
}
}
cout<<dp[n]<<endl;
return 0;
}
//输入6
//输出3 说明:1、5;2、4;1、2、3

7.多重背包,没做过题不好讲复习。。

多重背包问题限定了一种物品的个数,一个简单的方法,转成0-1背包。先这样写吧

#include <iostream>
using namespace std;
#define V 1000
int weight[50 + 1];
int value[50 + 1];
int num[20 + 1];
int f[V + 1];
int max(int a, int b) {
return a > b ? a : b;
}
int main() {
int n, m;
cout << "请输入物品个数:";
cin >> n;
cout << "请分别输入" << n << "个物品的重量、价值和数量:" << endl;
for (int i = 1; i <= n; i++) {
cin >> weight[i] >> value[i] >> num[i];
}
int k = n + 1;
for (int i = 1; i <= n; i++) {
while (num[i] != 1) {
weight[k] = weight[i];
value[k] = value[i];
k++;
num[i]--;
}
}
cout << "请输入背包容量:";
cin >> m;
for (int i = 1; i <= k; i++) {
for (int j = m; j >= 1; j--) {
if (weight[i] <= j) f[j] = max(f[j], f[j - weight[i]] + value[i]);
}
}
cout << "背包能放的最大价值为:" << f[m] << endl;
}

学长的dp:https://blog.csdn.net/o_ohello/article/details/89378697

dp小结|背包问题的更多相关文章

  1. 【dp】 背包问题

    问题一:01背包 题目: [题目描述] 一个旅行者有一个最多能装 M 公斤的背包,现在有 n件物品,它们的重量分别是W1,W2,...,Wn它们的价值分别为C1,C2,...,Cn求旅行者能获得最大总 ...

  2. 动态规划(DP),0-1背包问题

    题目链接:http://poj.org/problem?id=3624 1.p[i][j]表示,背包容量为j,从i,i+1,i+2,...,n的最优解. 2.递推公式 p[i][j]=max(p[i+ ...

  3. Codeforces Round #105 (Div. 2) E. Porcelain —— DP(背包问题)

    题目链接:http://codeforces.com/problemset/problem/148/E E. Porcelain time limit per test 1 second memory ...

  4. 「10.19」最长不下降子序列(DP)·完全背包问题(spfa优化DP)·最近公共祖先(线段树+DFS序)

    我又被虐了... A. 最长不下降子序列 考场打的错解,成功调了两个半小时还是没A, 事实上和正解的思路很近了,只是没有想到直接将前$D$个及后$D$个直接提出来 确实当时思路有些紊乱,打的时候只是将 ...

  5. [动态规划]状态压缩DP小结

     1.小技巧 枚举集合S的子集:for(int i = S; i > 0; i=(i-1)&S) 枚举包含S的集合:for(int i = S; i < (1<<n); ...

  6. 概率dp小结

    好久之前学过,记得是一次亚洲区的前几天看了看概率dp,然后亚洲区就出了一道概率dp,当时虽然做上了,但是感觉有很多地方没懂,今天起早温习了一下,觉得很多地方茅塞顿开,果然学习的话早上效果最好了. 首先 ...

  7. 状压DP小结

    看了一个多星期状压DP,总算有点明白,大概可以分为两种:数据是在矩阵中的,数据是线性的,在矩阵中的一般就是排兵布阵这一种的,还有一种线性结构中给定条件让你求最大权值,比如求最大权值路线,TSP问题等, ...

  8. 状态压缩dp小结

    最近一段时间算是学了一些状态压缩的题目,在这里做个小结吧 首先是炮兵布阵类题目,这类题目一开始给定一个矩形,要求在上面放置炮兵,如果在一格放了炮兵那么周围的某些格子就不能放炮兵,求最大能放置炮兵的数量 ...

  9. 数位dp小结

    数位dp其实就是一种用来求区间[l, r]满足条件的数的个数.数位是指:个十百千万,而在这里的dp其实相当于暴力枚举每一位数. 我们通过把l, r的每位数分解出来,然后分别求r里满足条件的数有多少,l ...

随机推荐

  1. Java多线程-----创建线程的几种方式

       1.继承Thread类创建线程 定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体 创建Thread子类的实例,也就是创建 ...

  2. Windsor

    https://github.com/castleproject/Windsor https://github.com/castleproject/Windsor/blob/master/docs/R ...

  3. 【Hive学习之四】Hive 案例

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-3.1.1 apache-hive-3.1.1 ...

  4. Spring源码阅读(二)

    我们先看AbstractBeanFactory.getBean方法,这个方法通过bean名称类型等信息获取类实例,如果实例不存在则生产并缓存. //-------------------------- ...

  5. 基于Kubernetess集群部署完整示例——Guestbook

    目录贴:Kubernetes学习系列 本文依赖环境:Centos7部署Kubernetes集群.基于Kubernetes集群部署skyDNS服务 该示例中,我们将创建一个redis-master.两个 ...

  6. linux常用命令:rm 命令

    昨天学习了创建文件和目录的命令mkdir ,今天学习一下linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所 ...

  7. Java技术整理1---反射机制及动态代理详解

    1.反射是指在程序运行过程中动态获取类的相关信息,包括类是通过哪个加载器进行加载,类的方法和成员变量.构造方法等. 如下示例可以通过三种方法根据类的实例来获取该类的相关信息 public static ...

  8. vue对比其他框架详细介绍

    vue对比其他框架详细介绍 对比其他框架 — Vue.jshttps://cn.vuejs.org/v2/guide/comparison.html React React 和 Vue 有许多相似之处 ...

  9. Zsh和oh my zsh的安装和使用

    Zsh 兼容 Bash,据传说 99% 的 Bash 操作 和 Zsh 是相同的,默认 CentOS / Ubuntu / Mac 系统用的是 Bash,倒也不是说 Bash 不好,而是说我们有更好的 ...

  10. 关于Eclipse新建Dynamic Web Projecj默认未创建web.xml的问题

    当使用eclipse新建Dynamic Web Projecj时,由于J2EE技术规范的更新,当使用Dynamic web module version默认版本为3.0时,将默认不会创建web.xml ...