第四十五章 动态规划——背包问题模型(二)

news2025/1/15 13:21:46

一、概述

我们在上一章中已经对背包模型做了一定地讲解,但是我们发现其实在上一章节中我们所介绍的例题大部分是给背包问题套上一个背景,当我们识破了背后的模型后,我们就可以直接套用模板,基本不需要对代码做改变。

那么在这一章节中,我们将讲解一些在背包问题代码上做出一定改变的题目。比如求方案数,方案等等。

二、例题

1、AcWing 1020. 潜水员

(1)问题

在这里插入图片描述

(2)分析

这道题表面上是一个二维费用背包模型,但是在模型题目中,我们的状态f[i][j][k]表示的是体积至多是j,重量至多是k,也就是一个小于等于的大小关系。

但是这道题不一样,我们要保证氧气和氮气足量,也就说可以多不能少,那么如果用二维费用背包模型表达的话,即状态f[i][j][k]表示的是体积至少是j,重量至少是k,反而是一个大于等于的大小关系。

由于状态含义的改变,我们的代码一定会改变,这里还涉及到了下标为负数时的处理。作者在之前的文章中做过详细地讲解,大家可以去看一看:AcWing 1020. 潜水员(二维费用背包的变形)详解

(3)代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1010;
int n,m,k;
int o2[N],n2[N],w[N];
int f[N][30][80];
int main()
{
    cin>>m>>n>>k;
    for(int i=1;i<=k;i++)scanf("%d%d%d",o2+i,n2+i,w+i);
    memset(f,0x3f,sizeof f);
    f[0][0][0]=0;
    for(int i=1;i<=k;i++)
    {
        for(int j=0;j<=m;j++)
        {
            for(int p=0;p<=n;p++)
            {
                f[i][j][p]=f[i-1][j][p];
                int m1=min(j,o2[i]),m2=min(p,n2[i]);
                f[i][j][p]=min(f[i-1][j-m1][p-m2]+w[i],f[i][j][p]);
            }
        }
    }
    cout<<f[k][m][n]<<endl;
    return 0;
}

2、AcWing 7. 混合背包问题

(1)问题

在这里插入图片描述

(2)分析

这道题则是各种背包问题的融合,只有大家掌握了各种单一的背包问题才能来解决这道题,但是如何将各种问题融合起来则是这道题的难点。也需要我们对代码模板做一定的改变和拼接。

详解请看:混合背包问题详解

(3)代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2e4+10;
int f[N];
int n,m,v,w,s;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&v,&w,&s);
        if(!s)
        {
            for(int j=v;j<=m;j++)
                f[j]=max(f[j],f[j-v]+w);
        }
        else
        {
            if(s==-1)s=1;
            int k;
            for(k=1;k<=s;k*=2)
            {
                for(int j=m;j>=k*v;j--)
                {
                    f[j]=max(f[j],f[j-k*v]+k*w);
                }
                s-=k;
            }
            if(s)
            {
                for(int j=m;j>=s*v;j--)
                {
                    f[j]=max(f[j],f[j-s*v]+s*w);
                }
            }
        }
    }
    cout<<f[m]<<endl;
    return 0;
}

3、AcWing 12. 背包问题求具体方案

(1)问题

在这里插入图片描述

(2)分析

这道题也是求方案数,但是为了满足题目中最小字典序的条件,我们需要更改状态转移方程中的状态定义。这一点是比较难的。作者在之前的文章中做过介绍,不懂的同学可以去看一看:AcWing 12. 背包问题求具体方案

(3)代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1010;
int v[N],w[N],f[N][N],cnt[N];
int n,m;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)scanf("%d%d",v+i,w+i);
    for(int i=n;i>=1;i--)
    {
        for(int j=0;j<=m;j++)
        {
            f[i][j]=f[i+1][j];
            if(j>=v[i])f[i][j]=max(f[i][j],f[i+1][j-v[i]]+w[i]);
        }
    }
    int j=m;
    int count=0;
    for(int i=1;i<=n;i++)
        if(j>=v[i]&&f[i+1][j-v[i]]+w[i]==f[i][j])
        {
            cout<<i<<" ";
            j-=v[i];
        }

    return 0;
}

4、AcWing 11. 背包问题求方案数

(1)问题

在这里插入图片描述

(2)分析

这道题也是求方案,但是这次求的时方案数目,而这个过程也是一个DP,而这个DP的书写则需要用01背包的思路来写。所以这道题是利用背包问题的思想去解决新的问题,详解请看:
AcWing 11. 背包问题求方案数

(3)代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1010,mod=1e9+7;
int f[N],g[N];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<=m;i++)g[i]=1;
    for(int i=1;i<=n;i++)
    {
        int v,w;
        cin>>v>>w;
        for(int j=m;j>=v;j--)
        {
            if(f[j]<f[j-v]+w)
            {
                g[j]=g[j-v];
                f[j]=f[j-v]+w;
            }
            else if(f[j]==f[j-v]+w)
                g[j]=(g[j]+g[j-v])%mod;
        }
    }
    cout<<g[m]<<endl;
    return 0;
}

5、AcWing 1013. 机器分配

(1)问题

在这里插入图片描述

(2)分析

这道题是分组背包的应用,以及在分组背包的条件下如何求方案的问题,详解请看:AcWing 1013. 机器分配(分组背包问题与方案记录)

(3)代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=15,M=20;
int f[N][M],v[N][M],w[N][M];
int way[N];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&w[i][j]);
            v[i][j]=j;
        }
    
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=m;j++)
        {
            for(int k=0;k<=m;k++)
            {
                if(j>=v[i][k])
                f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
            }
        }
    }
    
    cout<<f[n][m]<<endl;
    int j=m;
    for(int i=n;i>=1;i--)
    {
        for(int k=0;k<=m;k++)
        {
            if(j>=v[i][k]&&f[i][j]==f[i-1][j-v[i][k]]+w[i][k])
            {
                way[i]=k;
                j-=k;
                break;
            }
        }
    }
    for(int i=1;i<=n;i++)cout<<i<<" "<<way[i]<<endl;   
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/178683.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot读写Redis客户端并实现技术切换(Jedis)

SpringBoot整合Redishttps://blog.csdn.net/weixin_51882166/article/details/128759780?spm1001.2014.3001.5501 读写客户端 首先应该打开redis服务&#xff1b; cd命令进入Redis安装目录下&#xff1a; 进入Redis客户端&#xff1a; redis-cli.exe -h 127.0.0.1 -p 6379…

梯度下降算法有哪些?有什么区别?【背景、原理、公式、代码】

一、梯度下降算法背景 梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯…

行为型模式-职责链模式

1.概述 在现实生活中&#xff0c;常常会出现这样的事例&#xff1a;一个请求有多个对象可以处理&#xff0c;但每个对象的处理条件或权限不同。例如&#xff0c;公司员工请假&#xff0c;可批假的领导有部门负责人、副总经理、总经理等&#xff0c;但每个领导能批准的天数不同…

记一段相亲反思

记一段相亲反思项目系统启动项目相亲需求的细分高净值人群特定类型的高预期结婚结婚前的彩礼引流系统启动流量&#xff0c;从哪里来&#xff1f;作弊避险&#xff0c;什么钱不能赚&#xff1f;这不是一篇找对象的文章&#xff0c;而是帮别人找对象来赚钱的文章。 项目系统 启…

洛谷-P2114 [NOI2014] 起床困难综合症

题目链接: P2114 [NOI2014] 起床困难综合症 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述: 21 世纪&#xff0c;许多人得了一种奇怪的病&#xff1a;起床困难综合症&#xff0c;其临床表现为&#xff1a;起床难&#xff0c;起床后精神不佳。作为一名青春阳光好少…

Bayesian Personalized Ranking from Implicit Feedback 阅读笔记

Abstract BPR主要用于基于隐式反馈(implicit feedback)的Item Recommendation。 尽管有很多做同样事情的算法比如matrix factorization&#xff0c; knearest-neighbor。但他们并不是直接对于物品排名本身进行预测的。 而BPR则是通过贝叶斯分析得到最大的后验估计量来预测排…

基于蜣螂算法优化概率神经网络PNN的分类预测-附代码

基于蜣螂算法优化概率神经网络PNN的分类预测 - 附代码 文章目录基于蜣螂算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立3.基于蜣螂优化的PNN网络5.测试结果6.参考文献7.Matlab代码摘要&#xff1a;针对PNN神经网络的光滑因…

[GYCTF2020]EasyThinking (ThinkPHP V6.0.0)

[GYCTF2020]EasyThinking 打开以后就注册一些功能&#xff0c;注册admin admin&#xff0c;成功然后尝试search这个方法是否有任意文件读取漏洞&#xff0c;试了试没有任何的回显。 然后个人中心&#xff0c;显示的是自己的历史命令 接下来&#xff0c;呃呃呃就没思路了&…

DFS(五)N皇后

51. N 皇后 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案…

★ 我的世界各类奇葩武器实现!(命令方块1.13+)

新版execute一出很多玩家都不会了。开头先给大家说一下怎么以旧换新&#xff1a; e.g. 旧版&#xff1a; /execute e[typearrow] ~ ~ ~ summon tnt 新版就改为&#xff1a; /execute at e[typearrow] run summon tnt 非常简单&#xff01; 注记 以下代码块里的命令未经表明一…

Mysql入门技能树-数据类型

数值的隐式类型转换 Joe 需要使用下列表做一项数值计算 create table points(id int primary key auto_increment,x int,y int );计算查询为&#xff1a; select id, (x^2 y^2)/2 as result from points; 得到的结果集中&#xff0c;result 列的类型应该是&#xff1a; 答…

剑指Offer 第1天 第2天

第 1 天 栈与队列&#xff08;简单&#xff09; 剑指 Offer 09. 用两个栈实现队列 class CQueue { public: CQueue() {} void appendTail(int value) { s1.push(value); } int deleteHead() { while(!s1.empty()) { …

AtCoder Regular Contest 154 C. Roller(思维题)

题目 T(T<5e3)组样例&#xff0c;每次给定一个数n(n<5e3)&#xff0c; 和长为n的两个数组a,b&#xff0c;你可以执行以下操作任意次&#xff1a; 操作&#xff1a;选择一个下标i(1<i<n)&#xff0c;将替换为&#xff0c;其中被认为是 问若干次操作后&#xff0…

JUC面试(十)——线程池Callable接口

线程池&Callable接口 前言 获取多线程的方法&#xff0c;我们都知道有三种&#xff0c;还有一种是实现Callable接口 实现Runnable接口实现Callable接口实例化Thread类使用线程池获取 Callable接口 这是一个函数式接口&#xff0c;因此可以用作lambda表达式或方法引用的…

JDBC连接池多线程通过CountDownLatch实现线程并发执行

目录 1.连接池 1.1 什么是连接池 1.2 为什么使用连接池 1.3 连接池的工作原理 1.4我们如何手写【难点】 1.4.1编写说明 1.4.2 创建jdbc.properties 1.4.3 封装一个连接类 1.4.4 创建一个连接池接口 1.4.5 创建一个连接池实现类以及对应方法 1.4.6 创建一个连接池的维…

spingboot如何接受前端请求

首先我们是否用的是rest风格开发的的都是适用的.普通参数get 请求发送方注:由于是get请求不用body(json)接收.接受方post请求发送端注意:在请求体(body)里面用x-www-from-urlencoded(不仅可以发请求,还可以发文件)接受体没有5种不同参数类型的传递普通参数[简单数据]&#xff1…

用 Java 实现计算器功能

练习一 1.设计一个类模拟一个计算器 达到什么需求&#xff1f;加减乘除 需要设计一个方法一个计算方法 控制台输出 首先请输入第一个数 例如数字 1 请输入符号 例如 请输入第二个数 例如 2 第二次 数字 3 请输入符号 - 请输入第二个数 2 结果 1 程序解析&#…

27. 作用域

1. 定义 作用域就是一个 python 程序可以直接访问命名空间的正文区域。 在一个 python 程序中&#xff0c;直接访问一个变量&#xff0c;会从内到外依次访问所有的作用域直到找到&#xff0c;否则会报未定义的错误。 python 中&#xff0c;程序的变量并不是在哪个位置都可以访…

【Hadoop】MapReduce原理剖析(Map,Shuffle,Reduce三阶段)

文章目录1. Map阶段1.1 把输入文件(夹)划分为很多InputSplit(Split)1.2 分配并执行map作业2. Shuffle阶段2.1 Partition(分区)2.2 Sort(排序)2.3 Group(分组)2.4 Combiner(规约)2.5 序列化并写入Linux磁盘内存2.6 反序列化读取数据到不同的reduce节点2.7 Reduce端数据进行合并、…

【数据库概论】第五章 数据库完整性

第五章 数据库完整性 目录第五章 数据库完整性5.1 实体完整性5.2 参照实体性5.3 用户定义的完整性1.属性上的约束条件2.元组上的约束条件5.4 完整性约束命名子句5.5 域中的完整性限制5.6 断言5.7 触发器(Trigger)一、定义触发器二、激活触发器三、删除触发器数据库的完整性指的…