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. [Linux] 快速修改hosts访问github

    sudo sed -i '/github/d' /etc/hosts sudo bash -c "curl https://gitlab.com/ineo6/hosts/-/raw/mast ...

  2. 关闭mysql上锁的表/数据

    一.输入查询语句,查看是否有数据被上锁 select * from information_schema.innodb_trx; 取 trx_mysql_thread_id 字段值 kill < ...

  3. Python 中read()、 readline() 、readlines()三者之间的区别?

    read()方法用于一次性读取整个文件的内容,并将其作为一个字符串返回. readline()方法用于逐行读取文件的内容.每次调用readline()方法,它会读取文件的下一行,并将其作为一个字符串返 ...

  4. Redis基础_五大数据类型和常用命令

    ## 1. Redis基本介绍 1.1 传统数据存储出现的问题 海量用户 高并发 罪魁祸首--关系型数据库: 性能瓶颈:磁盘IO性能低下 扩展瓶颈:数据关系复杂,扩展性差,不便于大规模集群 解决思路 ...

  5. Java 数组查找

    1 //要找的数 - 数组中的第一个元素 / 最大的数 - 第一个元素 2 //数组的查找(线性查找 二分法查找) 3 //线性查找: 4 //equals 5 6 String dest = &qu ...

  6. [.Net]使用Soa库+Abp搭建微服务项目框架(三):项目改造

    ​上一章我们说道,如果要使各模块之间解耦,使得各自独立成服务,首先要解除各个模块之间的引用关系. 还记得上一章我们的小项目吗 ?们回到之前的代码上来,当前的项目架构如下图: ​ 这次的任务是将它改造成 ...

  7. docker 资料整理

    docker 资料整理 基础概念 docker deamon 守护系统:简单理解就是docker的软件系统,管控这容器的开关. docker容器:从镜像启动到内存中形成动态运行,从编程角度,如果镜像是 ...

  8. async await $api vue

    async getDataNew () { const res = await this.$api('apiPath') if (res && res.status === 20) { ...

  9. 关于Jitpack发布aar,会丢失内置依赖库问题

    原文:关于Jitpack发布aar,会丢失内置依赖库问题 | Stars-One的杂货小窝 关于发布aar出现的一个大坑排查,折腾了两天,终于是找到了解决方案 问题描述 有这样的一个情况,我新建了个A ...

  10. [原创] KCP 源码分析(上)

    KCP 协议是一种可靠的传输协议,对比 TCP 取消了累计确认(延迟 ACK).减小 RTO增长速度.选择性重传而非全部重传.通过用流量换取低时延. KCP 中最重要的两个数据结构IKCPCB和IKC ...