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的更多相关文章

  1. [luogu1156]垃圾陷阱_动态规划_背包dp

    垃圾陷阱 luogu-1156 题目大意:Holsteins在距离地面D英尺的地方,FJ间隔时间ti会往下扔第i个垃圾.Holsteins对待每一个垃圾都会选择吃掉或者垫高.Holsteins有10个 ...

  2. [bzoj1708][Usaco2007 Oct]Money奶牛的硬币_动态规划_背包dp

    Money奶牛的硬币 bzoj-1708 Usaco-2007 Oct 题目大意:在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统的货币 ...

  3. 算法竞赛模板 动态规划之背包DP

    ① 01背包 有n件物品和一个容量为v的背包.第i件物品的价值是c[i],体积是w[i].求解将哪些物品装入背包可使价值总和最大. 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. ...

  4. [bzoj1606][Usaco2008 Dec]Hay For Sale 购买干草_动态规划_背包dp

    Hay For Sale 购买干草 bzoj-1606 Usaco-2008 Dec 题目大意:约翰遭受了重大的损失:蟑螂吃掉了他所有的干草,留下一群饥饿的牛.他乘着容量为C(1≤C≤50000)个单 ...

  5. [bzoj2748][HAOI2012]音量调节_动态规划_背包dp

    音量调节 bzoj-2748 HAOI-2012 题目大意:有一个初值,给你n个$\delta$值,求最后不超过给定的限制的情况下的改变的最大值.每个$\delta$值可以+也可以-. 注释:$1\l ...

  6. [USACO Section 5.3]量取牛奶 Milk Measuring (动态规划,背包$dp$)

    题目链接 Solution 完全背包 \(dp\) , 同时再加一个数组 \(v[i][j]\) 记录当总和为\(j\) 时第 \(i\) 种物品是否被选. 为保证从小到大和字典序,先将瓶子按大小排序 ...

  7. 背包dp整理

    01背包 动态规划是一种高效的算法.在数学和计算机科学中,是一种将复杂问题的分成多个简单的小问题思想 ---- 分而治之.因此我们使用动态规划的时候,原问题必须是重叠的子问题.运用动态规划设计的算法比 ...

  8. 动态规划_线性dp

    https://www.cnblogs.com/31415926535x/p/10415694.html 线性dp是很基础的一种动态规划,,经典题和他的变种有很多,比如两个串的LCS,LIS,最大子序 ...

  9. 「kuangbin带你飞」专题十二 基础DP

    layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...

  10. 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 ...

随机推荐

  1. rt_snprintf()是什么

    在c++中snprintf()函数的解释 1,函数原型: int snprintf(char* dest_str,size_t size,const char* format,...); 2,功能 将 ...

  2. SpringCloud zookeeper和consul 的介绍和基本搭建

    1. Spring Cloud 集成 zookeeper Spring Cloud 集成了 zookeeper ,通过一些简单的注释,就可以快速注册到zookeeper 服务中 并且支持Spring ...

  3. Rsync 备份服务搭建

    Rsync 备份服务搭建 目录 Rsync 备份服务搭建 一. 前言 二. rsync 和 sersync 2.1 rsync 基本语法 2.2 本地文件传输 2.3 ssh 远程文件传输 2.4 基 ...

  4. 清除 gitee.io 页面强缓存 Chrome浏览器 F12 找到页面 右键 Clear browser cache

    清除 gitee.io 页面强缓存 Chrome浏览器 F12 找到页面 右键 Clear browser cache

  5. snipaste 替换 微信截图快捷键 F3贴图功能实在是太帅了 - 软件推荐

    snipaste 替换 微信截图快捷键 这个软件很久之前就知道,一直也没觉得可以替换微信的截图功能,毕竟能懒就懒. 今天同事又推荐 用了下,觉得确实ok. https://zh.snipaste.co ...

  6. Spring Boot学习日记12

    学习了Thymeleaf模板引擎前端交给我们的页面,是html页面.如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据 ...

  7. 基于PyQGIS实现遥感影像下载

    1. 引言 之前的文章:QGIS中下载遥感影像的Python代码片段 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com),记述了在 QGIS 的 Python Console 中使用Py ...

  8. Python 生成二维码的几种方式、生成条形码

    一: # 生成地维码 import qrcode import matplotlib.pyplot as plt from barcode.writer import ImageWriter 创建QR ...

  9. C# AES CBC模式 加密和解密

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.S ...

  10. CLion和WSL配置MPI运行及调试环境

    本文将介绍 Windows 下,使用 CLion 和 WSL 配置 MPI 运行及调试环境的方法. 0. 前提 阅读本文前,请确保: Windows 下已启用 WSL2,并安装了任一 Linux 发行 ...