动态规划(二)——背包dp


01背包问题(每个物品最多选一次)


AcWing 2. 0/1背包问题

朴素の版本:
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int vi[N],wi[N],f[N][N];
int n,v;
int main(){
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++) scanf("%d%d",&vi[i],&wi[i]);
for(int i=1;i<=n;i++){
for(int j=0;j<=v;j++){
f[i][j]=f[i-1][j];
if(j>=v[i]) f[i][j]=max(f[i][j],f[i-1][j-vi[i]]+wi[i]);
}
}
printf("%d",f[n][v]);
return 0;
}
滚动数组优化の版本:
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int vi[N],wi[N],f[N][N];
int n,v;
int main(){
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++) scanf("%d%d",&vi[i],&wi[i]);
for(int i=1;i<=n;i++){
for(int j=0;j<=v;j++){
f[i&1][j]=f[(i-1)&1][j];
if(j>=v[i]) f[i&1][j]=max(f[i&1][j],f[(i-1)&1][j-vi[i]]+wi[i]);
}
}
printf("%d",f[n&1][v]);
return 0;
}
有不了解滚动数组的读者,可以参考以下大佬博客:
https://www.cnblogs.com/kimsimple/p/6883871.html
终极优化の版本:(二维变一维)
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int vi[N],wi[N],f[N];
int n,v;
int main(){
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++) scanf("%d%d",&vi[i],&wi[i]);
for(int i=1; i<=n; i++){
for(int j=v; j>=vi[i]; j--){
f[j]=max(f[j],f[j-vi[i]]+wi[i]);
}
}
printf("%d", f[v]);
return 0;
}
完全背包问题(每个物品可以选无限多次)


AcWing 3. 完全背包问题

朴素の版本:
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int vi[N],wi[N],f[N][N];
int n,v;
int main(){
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++) scanf("%d%d",&vi[i],&wi[i]);
for(int i=1;i<=n;i++){
for(int j=0;j<=v;j++){
for(int k=0;k*vi[i]<=j;k++){
f[i][j]=max(f[i][j],f[i-1][j-k*vi[i]]+k*wi[i]);
}
}
}
printf("%d", f[n][v]);
return 0;
}
二维数组の版本:

二维数组优化の版本:
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int vi[N],wi[N],f[N][N];
int n,v;
int main(){
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++) scanf("%d%d",&vi[i],&wi[i]);
for(int i=1;i<=n;i++){
for(int j=0;j<=v;j++){
f[i][j]=f[i-1][j];
if(j>=vi[i]) f[i][j]=max(f[i][j],f[i][j-vi[i]]+wi[i]);
}
}
printf("%d",f[n][v]);
return 0;
}
终极优化の版本:
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int vi[N],wi[N],f[N];
int n,v;
int main(){
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++) scanf("%d%d",&vi[i],&wi[i]);
for(int i=1;i<=n;i++){
for(int j=vi[i];j<=v;j++){
f[j]=max(f[j],f[j-vi[i]]+wi[i]);
}
}
printf("%d",f[v]);
return 0;
}
多重背包问题(有限次地选每件物品)---二进制优化版本




多重背包问题

二进制拆分の版本:
#include <bits/stdc++.h>
using namespace std;
const int N=15000;
const int M=2010;
int n,m,cnt;
int f[M];
int v[N],w[N],s[N];
int main(){
int vi=0,wi=0,si=0;
scanf("%d%d", &n, &m);
//二进制拆分
for(int i=1;i<=n;i++){
scanf("%d%d%d",&vi,&wi,&si);
if(si>m/vi) si=m/vi;
for(int j=1;j<=si;j<<=1){
v[++cnt]=j*vi;
w[cnt]=j*wi;
si-=j;
}
if(si>0){
v[++cnt]= si*vi;
w[cnt]=si*wi;
}
}
//0/1背包
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]);
}
}
printf("%d",f[m]);
return 0;
}
分组背包问题(n组,每组只能选一种并且最多选一次)

分组背包问题

朴素の版本:
#include <bits/stdc++.h>
using namespace std;
const int N=40;
const int M=210;
int n,m,t;
int v[N],c[N];
int g[15][N],f[15][M];
int main(){
int x=0;
scanf("%d%d%d",&m,&n,&t);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&v[i],&c[i],&x);
g[x][++g[x][0]]=i;
}
for(int i=1;i<=t;i++){
for(int j=0;j<=m;j++){
f[i][j]=f[i-1][j];
for(int k=1;k<=g[i][0];k++){
if(j>=v[g[i][k]]) {
x=g[i][k];
f[i][j]=max(f[i][j],f[i-1][j-v[x]]+c[x]);
}
}
}
}
printf("%d",f[t][m]);
return 0;
}
终极优化の版本:
#include <bits/stdc++.h>
using namespace std;
const int N=40;
const int M=210;
int n,m,t;
int v[N],c[N],g[15][N];
int f[M];
int main(){
int x=0;
scanf("%d%d%d",&m,&n,&t);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&v[i],&c[i],&x);
g[x][++g[x][0]]=i;
}
for(int i=1;i<=t;i++){
for(int j=m;j>=0;j--){
for(int k=1; k<=g[i][0]; k++){
if(j>=v[g[i][k]]) {
x=g[i][k];
f[j]=max(f[j],f[j-v[x]]+c[x]);
}
}
}
}
printf("%d",f[m]);
return 0;
}
以上就是背包dp中几个类型的问题了,如有错误欢迎大家在评论区指正小蒟蒻博主的错误~
本文图片来自https://blog.csdn.net/m0_73569492/article/details/129864277鸣谢大佬
#一名爱打篮球的oier#
动态规划(二)——背包dp的更多相关文章
- [luogu1156]垃圾陷阱_动态规划_背包dp
垃圾陷阱 luogu-1156 题目大意:Holsteins在距离地面D英尺的地方,FJ间隔时间ti会往下扔第i个垃圾.Holsteins对待每一个垃圾都会选择吃掉或者垫高.Holsteins有10个 ...
- [bzoj1708][Usaco2007 Oct]Money奶牛的硬币_动态规划_背包dp
Money奶牛的硬币 bzoj-1708 Usaco-2007 Oct 题目大意:在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统的货币 ...
- 算法竞赛模板 动态规划之背包DP
① 01背包 有n件物品和一个容量为v的背包.第i件物品的价值是c[i],体积是w[i].求解将哪些物品装入背包可使价值总和最大. 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. ...
- [bzoj1606][Usaco2008 Dec]Hay For Sale 购买干草_动态规划_背包dp
Hay For Sale 购买干草 bzoj-1606 Usaco-2008 Dec 题目大意:约翰遭受了重大的损失:蟑螂吃掉了他所有的干草,留下一群饥饿的牛.他乘着容量为C(1≤C≤50000)个单 ...
- [bzoj2748][HAOI2012]音量调节_动态规划_背包dp
音量调节 bzoj-2748 HAOI-2012 题目大意:有一个初值,给你n个$\delta$值,求最后不超过给定的限制的情况下的改变的最大值.每个$\delta$值可以+也可以-. 注释:$1\l ...
- [USACO Section 5.3]量取牛奶 Milk Measuring (动态规划,背包$dp$)
题目链接 Solution 完全背包 \(dp\) , 同时再加一个数组 \(v[i][j]\) 记录当总和为\(j\) 时第 \(i\) 种物品是否被选. 为保证从小到大和字典序,先将瓶子按大小排序 ...
- 背包dp整理
01背包 动态规划是一种高效的算法.在数学和计算机科学中,是一种将复杂问题的分成多个简单的小问题思想 ---- 分而治之.因此我们使用动态规划的时候,原问题必须是重叠的子问题.运用动态规划设计的算法比 ...
- 动态规划_线性dp
https://www.cnblogs.com/31415926535x/p/10415694.html 线性dp是很基础的一种动态规划,,经典题和他的变种有很多,比如两个串的LCS,LIS,最大子序 ...
- 「kuangbin带你飞」专题十二 基础DP
layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...
- Codeforces 2016 ACM Amman Collegiate Programming Contest A. Coins(动态规划/01背包变形)
传送门 Description Hasan and Bahosain want to buy a new video game, they want to share the expenses. Ha ...
随机推荐
- 用 NetworkX + Gephi + Nebula Graph 分析<权力的游戏>人物关系(上篇)
我们都知道<权利的游戏>在全世界都很多忠实的粉丝,除去你永远不知道剧情下一秒谁会挂这种意外"惊喜",当中复杂交错的人物关系也是它火爆的原因之一,而本文介绍如何通过 Ne ...
- vscodeC++生成配置文件
参考 https://www.cnblogs.com/harrypotterisdead/p/14207866.html 和 https://www.cnblogs.com/heyiping/p/14 ...
- k8s安全之Network Policy
K8s Network Policy 是一种资源,它用于在 Pod 之间以及从其他网络实体到 Pod 的通信中进行网络级别的访问控制.它允许您定义一组规则,这些规则可以指定允许或拒绝网络流量. 具体来 ...
- 基于python的指定时段执行实例解析
一 概念: python中库很多,这里熟悉下time和interval的用法 二 实例解析 切记这里的interval,输出的是目前的时间是一个数组. import time from interva ...
- day01-2-导入驱动和工具类
满汉楼01-2 4.功能实现01 4.1导入驱动和工具类 4.1.1导入驱动 首先将连接mysql的相关jar包引入项目中,分别右键,点击add as library 4.1.2导入工具类Utilit ...
- 告别繁琐!1分钟带你构建RabbitMQ消息应用
支持.Net/.Net Core/.Net Framework,可以部署在Docker, Windows, Linux, Mac. RabbitMQ作为一款主流的消息队列工具早已广受欢迎.相比于其它的 ...
- RAG 范式、技术和趋势
这里分享同济大学 Haofen Wang的关于检索增强生成的报告:<Retrieval-Augmented Generation (RAG): Paradigms, Technologies, ...
- 简单对比Java、Python、Go、Rust等常见语言计算斐波拉契数的性能
前言 最近简单学了下Rust,以我这种菜鸟水平,没感受到什么安全.性能什么方面的优势,只觉得概念太多,编译各种报错.暂时也写不出来什么玩法,索性对比下各种学过的语言的性能.部分语言很早之前学过,很久不 ...
- python面向对象(基础)
一 面向对象介绍 面向过程: 核心是:"过程"二字 过程的终极奥义就是将程序流程化 过程是"流水化",用来分步骤解决问题的 面向对象: 核心是"对象& ...
- 从时间复杂度的角度出发,list和vector之间查找,插入,删除等数据操作的区别
list和vector是STL(标准模板库)中常用的两种序列容器,它们各自在不同类型的操作上有着不同的优势.下面是list和vector在不同操作上的擅长之处: list的擅长操作 插入和删除操作:l ...