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. Android -- 使用WindowManager实现悬浮框效果

    1,原文在这里http://blog.csdn.net/qq_17250009/article/details/52908791,我只是把里面的关键步骤给注释了一下,首先来看一下我们的效果,如图(电脑 ...

  2. <5>Cocos Creator 脚本简介

    1.创建脚本 在资源管理器窗口中点击鼠标右键,显示菜单中点击新建,选择新建的脚本类型,这里举例就选择菜单中的JavaScript,或者如下图点击创建按钮也可. 新建后就会在资源管理器中出现一个NewS ...

  3. CSS radial-gradient() 函数实现渐变

    值 描述 shape 确定圆的类型: ellipse (默认): 指定椭圆形的径向渐变. circle :指定圆形的径向渐变 size 定义渐变的大小,可能值: farthest-corner (默认 ...

  4. sql server2000中使用convert来取得datetime数据类型样式(转)

    日期数据格式的处理,两个示例: CONVERT(varchar(16), 时间一, 20) 结果:2007-02-01 08:02/*时间一般为getdate()函数或数据表里的字段*/ CONVER ...

  5. Vue系列之 => 组件切换

    组件切换方式一 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  6. Cipher

    Description Bob and Alice started to use a brand-new encoding scheme. Surprisingly it is not a Publi ...

  7. Codeforces Round #324 (Div. 2) E

    这题贪心,考虑先放第一个,然后从第一个数在p中的位置, 不断的往前走,和在他后面的那些数组进行交换,因为这样交换可以提高最大的效率,就是说你花费了1但是使得两个点都朝他的木匾节点减少了1 #inclu ...

  8. 即时通信系统中实现全局系统通知,并与Web后台集成【附C#开源即时通讯系统(支持广域网)——QQ高仿版IM最新源码】

    像QQ这样的即时通信软件,时不时就会从桌面的右下角弹出一个小窗口,或是显示一个广告.或是一个新闻.或是一个公告等.在这里,我们将其统称为“全局系统通知”.很多使用C#开源即时通讯系统——GGTalk的 ...

  9. windows下配置lua环境

    1.进入lua官网http://www.lua.org/ 2.点击download 3.点击get a binary 4.点击[Lua - joedf's Builds] 5.选择适合自己的版本下载, ...

  10. javamail发送邮件及错误解决方法javax.mail.AuthenticationFailedException: failed to connect, no password specified?

    javamail发送邮件及错误解决方法javax.mail.AuthenticationFailedException: failed to connect, no password specifie ...