第45期:动态规划-背包问题
目录
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期:动态规划-背包问题相关推荐
- 贪婪算法、递归计算、动态规划背包问题
//贪婪算法计算背包问题public static double ksack(double[] values, double[] weights, int capacity){double load ...
- 直面Java第45期
转载自 直面Java第45期
- 精选| 2020年8月R新包推荐(第45期)
生物信息学习的正确姿势 NGS系列文章包括NGS基础.在线绘图.转录组分析 (Nature重磅综述|关于RNA-seq你想知道的全在这).ChIP-seq分析 (ChIP-seq基本分析流程).单细胞 ...
- 动态规划——背包问题(01背包问题)
动态规划--背包问题(01背包问题) 01背包问题(求最大价值): 问题优化 01背包问题(求方案数): 动态规划--背包问题(01背包问题) 01背包问题(求最大价值): 有N件物品和一个最多能背重 ...
- 【区块链技术工坊45期】陈军:用案例解析通证经济模型设计
1. 活动基本信息 1)题目: [区块链技术工坊45期]案例解析通证经济模型设计 2)议题: 传统的新技术出现,人们只需要精通其语言规范和工具即可付诸应用.而区块链技术的出现却伴随着一个新的经济概念, ...
- 软件测试周刊(第45期):一个人不该过分自省,这会使他变得软弱。
编辑:国薇.一口锅.菜菜.静怡.小淑子.夏至 欢迎来到第 45 期!这里记录过去一周我们看到的软件测试及周边的行业动态,周五发布. 本期看点:如何使用 Chrome 的新功能录制.重放和测试用户操作? ...
- 动态规划背包问题优化空间复杂度——滚动数组
动态规划背包问题优化空间复杂度--滚动数组 背包问题 空间复杂度优化 Java代码 链接:代码随想录背包问题 背包问题 背包问题是动态规划中基本的问题,我们考虑下面的简单问题: 假设背包容量为 ...
- 动态规划——背包问题(详解)
动态规划是我最早接触的算法,一开始非常简单,固定模板题,后来愈发愈发难起来了,条件,状态压缩等等,难点主要是,状态怎么表示,状态转移方程怎么写,这篇文章将会从背包五大问题详解,希望能帮助到大家去类比, ...
- 动态规划——背包问题
动态规划--背包问题 对于背包问题,今天我们先讲解,01背包,完全背包,和多重背包.我主要从: 什么题可以用背包问题解决 背包问题的模板细节,如何准确写出背包. 1.什么题可以用背包问题解决 看到题目 ...
- 动态规划背包问题详解(二)---0-1背包问题
/** * 对于技术面试,你还在死记硬背么? * 快来"播"沙糖橘吧, * 用视频案例为你实战解读技术难点 * 聚焦Java技术疑难点,实战视频为你答疑解惑 * 越&qu ...
最新文章
- oracle 主机名改ip,[oracle 10.2]主机名或者IP地址改变造成的dbconsole服务无法启动解决...
- android键盘弹出头部上移处理
- 何时使用hadoop fs、hadoop dfs与hdfs dfs命令
- 间接银团贷款(Indirectly Syndicated Loan/PARTICIPATED)
- 使用WTMPlus快速搭建发卡网
- Go语言中cannot convert adminname (type interface {}) to type *: need type assertion的解决办法...
- java使用队列实现栈思路_算法面试:队列实现栈的方案
- python 公众号菜单_Python脚本--微信公众号自定义菜单的创建及获取
- 鼠标点击TextBox控件后清空默认字体
- 算法:回溯十七 Combination Sum III挑选数组中规定个数元素的和为指定数
- 离散数学及其应用(一)
- 线性链表 — 单链表
- 今天不开心 和话痨机器人聊一会
- 5.1索引压缩-词项的统计特性(Heaps定律、Zipf定律)
- 月薪过万的java程序员需要什么能力_什么样能力的Java程序员月薪过万
- python读取tif图片_python读取tif图片时保留其16bit的编码格式实例
- Linux CPU 100%问题 | top 命令详解
- 计算机中pdf怎么预览,如何在浏览器中开启PDF时默认显示Adobe Reader XI工具栏
- 7-4 Swan学院社团招新 (20 分)
- python 计算召回率的程序_python实现计算精度、召回率和F1值
热门文章
- 452页24万字智慧城市顶层设计及智慧应用解决方案
- 图片文字识别,手机里的图片转文字的方法
- 父亲给儿子的一封信:当我日渐老去的时候
- 新手如何使用Github
- Redis高负载排查记录
- OpenCV cmake配置项BUILD_opencv_world的说明
- 用 nanodet 训练口罩检测模型,并在 jetson nano 下部署测试
- 暴雪网易事件大讨论:Web3游戏未来发展趋势
- 计算机存在其他连接设备错误,电脑连不上宽带,一直提示”调制解调器(或其它联接设备)报告了一个错误。“...
- 微软ATC的笔试面试经历