目录

1. 01背包

1. 2. 01背包问题 - AcWing题库

2.完全背包(无限背包)

1. 疯狂的采药 - 洛谷

3.多重背包

二进制优化多重背包

单调队列优化多重背包

4. 树形背包

1. [CTSC1997] 选课 - 洛谷

5. 分组背包

1. 通天之分组背包 - 洛谷

2. 9. 分组背包问题 - AcWing题库

6. 混合背包

1. 7. 混合背包问题 - AcWing题库(01背包+完全背包+多重背包)

7. 多维背包

二维:

1. 8. 二维费用的背包问题 - AcWing题库


闫氏DP分析法

总概:背包问题如下:

01背包
完全背包(无限背包)
多重背包
树形背包
分组背包
混合背包
多维背包

1. 01背包

参考:总结——01背包问题 (动态规划算法)_并非所有流浪者都迷失了自我-CSDN博客_01背包问题动态规划算法【动态规划】01背包问题(通俗易懂,超基础讲解)_Yngz_Miao的博客-CSDN博客_动态规划解决01背包问题

1. 2. 01背包问题 - AcWing题库

#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
int n,V;
int v[maxn],w[maxn];
int f[maxn][maxn];
int main(){cin>>n>>V;for(int i=1;i<=n;++i){cin>>v[i]>>w[i];}for(int i=1;i<=n;++i){for(int j=1;j<=V;++j){if(j<v[i]){f[i][j]=f[i-1][j];}else{f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]);}}}cout<<f[n][V]<<endl;return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int f[MAXN];  //
int main() {int n, m;   cin >> n >> m;for(int i = 1; i <= n; i++) {int v, w;cin >> v >> w;      // 边输入边处理for(int j = m; j >= v; j--)f[j] = max(f[j], f[j - v] + w);}cout << f[m] << endl;return 0;
}

2.完全背包(无限背包)

1. 疯狂的采药 - 洛谷

设 f(i,j)表示前 i 件物品采药 j 时间能获得的最大价值。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e4+5,M=1e7+5;
int n,m,w[N],v[N],f[M];
signed main(){cin>>m>>n;for(int i=1;i<=n;i++) cin>>w[i]>>v[i];for(int i=1;i<=n;i++)for(int j=w[i];j<=m;j++)f[j]=max(f[j],f[j-w[i]]+v[i]);cout<<f[m];return 0;
}

3.多重背包

参考:多重背包问题大全(超详细)_曼切斯特的流氓的博客-CSDN博客_多重背包问题

二进制优化多重背包

#include <iostream>
using namespace std;int n,m;//n个种类,m代表包总体积
int v[11010],w[11010];//v代表体积,w代表价值
int dp[2010];
int main()
{scanf("%d%d",&n,&m);int cnt=0;//cnt统计新的种类for(int i=1; i<=n; i++){int a,b,s;//体积,价值,数量scanf("%d%d%d",&a,&b,&s);//将s件用二进制转换为log2s堆for(int k=1; k<=s; k<<=1){v[++cnt]=k*a;//前++,第1种,第二种.....w[cnt]=k*b;s-=k;}if(s)//s有剩余,自立为新品种{v[++cnt]=s*a;w[cnt]=s*b;}}//01背包做法for(int i=1; i<=cnt; i++){for(int j=m; j>=v[i]; j--){dp[j]=max(dp[j],dp[j-v[i]]+w[i]);//动态转移方程和01背包完全相同}}printf("%d",dp[m]);return 0;
}

单调队列优化多重背包

#include<bits/stdc++.h>using namespace std;
int n,m;//n种,背包总体积为m
const int maxn=20010;
int f[maxn],g[maxn],q[maxn];//g数组用来复制,q用来形成单调队列,存放g中元素下标int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){memcpy(g,f,sizeof(f));//将数组f拷贝到g中int v,w,s;//体积、价值、件数scanf("%d%d%d",&v,&w,&s);//按照体积分为v类,每个类起点为0,1,....v-1for(int j=0;j<v;j++){int head=0,tail=-1;//遍历整个类for(int k=j;k<=m;k+=v){//利用单调队列滑动窗口模板if(head<=tail&&k-s*v>q[head]) head++;//队首元素,不在于滑动窗口,踢出队首元素//将在滑动区间内,中最大值,也就是单调队列中队首元素if(head<=tail) f[k]=max(g[k],g[q[head]]+(k-q[head])/v*w);//01背包动态转移方程//如果队尾元素小于g[k],则从队尾出队while(head<=tail&&g[k]>=g[q[tail]]+(k-q[tail])/v*w) tail--;//g[k]入队q[++tail]=k;}}}printf("%d\n",f[m]);return 0;
}

题目:

4. 多重背包问题 I - AcWing题库

5. 多重背包问题 II - AcWing题库

6. 多重背包问题 III - AcWing题库

(二进制优化可以解决4,5;单调队列优化能解决all)

4. 树形背包

参考:

树形背包 学习笔记_不知所云的博客-CSDN博客_树形背包、

树形dp:树形$dp$学习笔记 - _Lancy - 博客园

1. [CTSC1997] 选课 - 洛谷

不妨设f[now][j][k]表示以now为根节点的子树

考虑前j个节点选k门课的方案数

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=1000;
const int M=1000100;
const LL mod=100000000;
int n,m,head[N],cnt,w[N],in[N],dp[N][N];
struct Node{int to,nex;
}edge[N];
void add(int p,int q){edge[cnt].to=q;edge[cnt].nex=head[p];head[p]=cnt++;
}
void dfs(int p){dp[p][1]=w[p];for(int i=head[p];~i;i=edge[i].nex){int q=edge[i].to;dfs(q);for(int j=m;j>=1;j--){for(int k=j-1;k>=1;k--){dp[p][j]=max(dp[p][j],dp[p][j-k]+dp[q][k]);}}}
}
int main(){memset(head,-1,sizeof(head));scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int k,s;scanf("%d%d",&k,&s);if(k) add(k,i),in[i]++;w[i]=s;}for(int i=1;i<=n;i++){if(in[i]==0) add(0,i);}m++;dfs(0);cout<<dp[0][m]<<endl;return 0;
}
#include<iostream>
#include<cstdio>
#define maxn 1000
using namespace std;
int n,m,f[maxn][maxn],head[maxn],cnt;
struct edge
{int to,pre;
}e[maxn];
inline int in()
{char a=getchar();while(a<'0'||a>'9'){a=getchar();}int t=0;while(a>='0'&&a<='9'){t=(t<<1)+(t<<3)+a-'0';a=getchar();}return t;
}
void add(int from,int to)
{e[++cnt].pre=head[from];e[cnt].to=to;head[from]=cnt;
}
void dp(int now)
{
//    f[now][0]=0;for(int i=head[now];i;i=e[i].pre){int go=e[i].to;dp(go);for(int j=m+1;j>=1;j--){for(int k=0;k<j;k++){f[now][j]=max(f[now][j],f[go][k]+f[now][j-k]);}}}
}
int main()
{n=in(),m=in();for(int i=1;i<=n;i++){int fa=in();f[i][1]=in();add(fa,i);}dp(0);printf("%d\n",f[0][m+1]);return 0;
}

5. 分组背包

1. 通天之分组背包 - 洛谷

#include<bits/stdc++.h>
using namespace std;
int v,n,t;
int x;
int g[205][205];
int i,j,k;
int w[10001],z[10001];
int b[10001];
int dp[10001];
int main(){cin>>v>>n;for(i=1;i<=n;i++){cin>>w[i]>>z[i]>>x;//x表示第i个物品的小组编号t=max(t,x);//求小组组数b[x]++;//小组x的物品+1g[x][b[x]]=i;//g[i][j]表示存储小组i中的第j个物品的编号}for(i=1;i<=t;i++){//小组 for(j=v;j>=0;j--){//容量 for(k=1;k<=b[i];k++){//小组中的物品if(j>=w[g[i][k]]){//小组i中物品k的容量dp[j]=max(dp[j],dp[j-w[g[i][k]]]+z[g[i][k]]);//状态转移方程}}}}cout<<dp[v]<<endl;return 0;
}

2. 9. 分组背包问题 - AcWing题库

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int f[N];
int v[N][N],w[N][N],s[N];
int n,m,k;
int main(){cin>>n>>m;for(int i=0;i<n;i++){cin>>s[i];for(int j=0;j<s[i];j++){cin>>v[i][j]>>w[i][j];}}for(int i=0;i<n;i++){for(int j=m;j>=0;j--){for(int k=0;k<s[i];k++){    //for(int k=s[i];k>=1;k--)也可以if(j>=v[i][k])     f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);  }}}cout<<f[m]<<endl;
}

6. 混合背包

1. 7. 混合背包问题 - AcWing题库(01背包+完全背包+多重背包)

在本一道题当中,我们可以看到若此题为多重背包问题,那么按照数据范围来看,其实可以用多重背包问题2的方法来AK,先将01背包,完全背包转化成多重背包,01背包的话,则可以将物品数量写成1,而完全背包,则数量为(总体积(V)/该物品的体积(v[i]))。再按照多重背包的思路,即将多重背包转化成一个的二进制01背包来做即可

#include <bits/stdc++.h>
using namespace std;
int n,m,v[100010],w[100010],f[100010];
int main()
{cin>>n>>m;int cnt=1;for(int i=1;i<=n;i++){int a,b,s;cin>>a>>b>>s;int k=1;if(s<0)s=1;else if(s==0)s=m/a;//把01背包和多重背包先转化成多重背包,若为完全背包,则在最优情况下,只能取总体积/该物品体积向下取整 while(k<=s){v[cnt]=a*k;w[cnt]=b*k;s-=k;k*=2;cnt++;}if(s>0){v[cnt]=s*a;w[cnt]=s*b;cnt++;}}//将多重背包进行二进制优化,变成01背包 for(int i=1;i<=cnt;i++){for(int j=m;j>=v[i];j--){f[j]=max(f[j],f[j-v[i]]+w[i]);}}//01背包问题cout<<f[m]<<endl;return 0;
}

7. 多维背包

二维:

1. 8. 二维费用的背包问题 - AcWing题库

solution:AcWing 8. 二维费用的背包问题 - AcWing

#include <bits/stdc++.h>
using namespace std;
int n, V, M;
const int N = 1e3 + 5;
int v[N], m[N], w[N], f[N][N];
signed main () {cin >> n >> V >> M;for (int i = 1; i <= n; i ++) {cin >> v[i] >> m[i] >> w[i];//体积,重量,价值}for (int i = 1; i <= n; i ++)for (int j = V; j >= v[i]; j --)for (int k = M; k >= m[i]; k --)f[j][k] = max (f[j - v[i]][k - m[i]] + w[i], f[j][k]);//动态转移方程,01 背包的思路cout << f[V][M];
} 

第45期:动态规划-背包问题相关推荐

  1. 贪婪算法、递归计算、动态规划背包问题

    //贪婪算法计算背包问题public static double ksack(double[] values, double[] weights, int capacity){double load ...

  2. 直面Java第45期

    转载自 直面Java第45期

  3. 精选| 2020年8月R新包推荐(第45期)

    生物信息学习的正确姿势 NGS系列文章包括NGS基础.在线绘图.转录组分析 (Nature重磅综述|关于RNA-seq你想知道的全在这).ChIP-seq分析 (ChIP-seq基本分析流程).单细胞 ...

  4. 动态规划——背包问题(01背包问题)

    动态规划--背包问题(01背包问题) 01背包问题(求最大价值): 问题优化 01背包问题(求方案数): 动态规划--背包问题(01背包问题) 01背包问题(求最大价值): 有N件物品和一个最多能背重 ...

  5. 【区块链技术工坊45期】陈军:用案例解析通证经济模型设计

    1. 活动基本信息 1)题目: [区块链技术工坊45期]案例解析通证经济模型设计 2)议题: 传统的新技术出现,人们只需要精通其语言规范和工具即可付诸应用.而区块链技术的出现却伴随着一个新的经济概念, ...

  6. 软件测试周刊(第45期):一个人不该过分自省,这会使他变得软弱。

    编辑:国薇.一口锅.菜菜.静怡.小淑子.夏至 欢迎来到第 45 期!这里记录过去一周我们看到的软件测试及周边的行业动态,周五发布. 本期看点:如何使用 Chrome 的新功能录制.重放和测试用户操作? ...

  7. 动态规划背包问题优化空间复杂度——滚动数组

    动态规划背包问题优化空间复杂度--滚动数组 背包问题 空间复杂度优化 Java代码 链接:代码随想录背包问题 背包问题   背包问题是动态规划中基本的问题,我们考虑下面的简单问题:   假设背包容量为 ...

  8. 动态规划——背包问题(详解)

    动态规划是我最早接触的算法,一开始非常简单,固定模板题,后来愈发愈发难起来了,条件,状态压缩等等,难点主要是,状态怎么表示,状态转移方程怎么写,这篇文章将会从背包五大问题详解,希望能帮助到大家去类比, ...

  9. 动态规划——背包问题

    动态规划--背包问题 对于背包问题,今天我们先讲解,01背包,完全背包,和多重背包.我主要从: 什么题可以用背包问题解决 背包问题的模板细节,如何准确写出背包. 1.什么题可以用背包问题解决 看到题目 ...

  10. 动态规划背包问题详解(二)---0-1背包问题

    /**  * 对于技术面试,你还在死记硬背么?  * 快来"播"沙糖橘吧,  * 用视频案例为你实战解读技术难点  * 聚焦Java技术疑难点,实战视频为你答疑解惑  * 越&qu ...

最新文章

  1. oracle 主机名改ip,[oracle 10.2]主机名或者IP地址改变造成的dbconsole服务无法启动解决...
  2. android键盘弹出头部上移处理
  3. 何时使用hadoop fs、hadoop dfs与hdfs dfs命令
  4. 间接银团贷款(Indirectly Syndicated Loan/PARTICIPATED)
  5. 使用WTMPlus快速搭建发卡网
  6. Go语言中cannot convert adminname (type interface {}) to type *: need type assertion的解决办法...
  7. java使用队列实现栈思路_算法面试:队列实现栈的方案
  8. python 公众号菜单_Python脚本--微信公众号自定义菜单的创建及获取
  9. 鼠标点击TextBox控件后清空默认字体
  10. 算法:回溯十七 Combination Sum III挑选数组中规定个数元素的和为指定数
  11. 离散数学及其应用(一)
  12. 线性链表 — 单链表
  13. 今天不开心 和话痨机器人聊一会
  14. 5.1索引压缩-词项的统计特性(Heaps定律、Zipf定律)
  15. 月薪过万的java程序员需要什么能力_什么样能力的Java程序员月薪过万
  16. python读取tif图片_python读取tif图片时保留其16bit的编码格式实例
  17. Linux CPU 100%问题 | top 命令详解
  18. 计算机中pdf怎么预览,如何在浏览器中开启PDF时默认显示Adobe Reader XI工具栏
  19. 7-4 Swan学院社团招新 (20 分)
  20. python 计算召回率的程序_python实现计算精度、召回率和F1值

热门文章

  1. 452页24万字智慧城市顶层设计及智慧应用解决方案
  2. 图片文字识别,手机里的图片转文字的方法
  3. 父亲给儿子的一封信:当我日渐老去的时候
  4. 新手如何使用Github
  5. Redis高负载排查记录
  6. OpenCV cmake配置项BUILD_opencv_world的说明
  7. 用 nanodet 训练口罩检测模型,并在 jetson nano 下部署测试
  8. 暴雪网易事件大讨论:Web3游戏未来发展趋势
  9. 计算机存在其他连接设备错误,电脑连不上宽带,一直提示”调制解调器(或其它联接设备)报告了一个错误。“...
  10. 微软ATC的笔试面试经历