【背包问题】01背包问题和完全背包问题的模板

简介: 【背包问题】01背包问题和完全背包问题的模板

算法简述

      背包问题是一类经典的动态规划问题,背包问题分为:01背包问题,完全背包问题,多重背包问题和分组背包问题。这一类问题,我们可以使用闫式分析法,借鉴yxc大佬的思路创作的博客,以便自己复习和思考。

一、01背包问题(链接

1.1 问题描述

1.2 二维

1.2.1 二维思路讲解

      这是属于动态规划问题,我们一般可以从两个方面来分析动态规划问题:状态表示和状态计算。状态表示中分为:集合和属性。

      我们来先确定这个问题的集合:因为在题目中,我们可以知道时从N件物品中挑选出一些物品,且这些物品的总体积不超过背包容量,我们需要2个变量来进行表示状态:f[i][j] 表示的是我只从前 i 个物品中挑选出,且挑选出物品的总体积不超过 j。再来确定属性:因为存储的信息越少,越容易实现,所以一般情况下,这个属性是最大值、最小值……。

      状态计算也就是计算状态转移方程:我们需要根据题目要求来确定我们这个状态可以分为哪几种状态。通俗一点,也可以是集合划分。01背包问题是一个物品到底选不选,如果你不选择第i个物品就相当于在i - 1的物品中选择;如果你选择第i个物品就相当于我先都不选这个物品,那么这次的体积就不包含第i个物品的体积,我先算出这个种情况下,前i - 1个物品中的最大价值,之后再加入第i个物品的价值。

1.2.2 二维思路代码实现

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
 
const int N = 1010;
int n, m;
int v[N], w[N];
int f[N][N]; // 状态转移
 
int main()
{
  cin >> n >> m;
  for (int i = 1; i <= n; i++)  cin >> v[i] >> w[i];
  for (int i = 1; i <= n; i++)
  {
    for (int j = 0; j <= m; j++) // 枚举所有体积,所以开数组时,请开到体积的大小
    {
      f[i][j] = f[i - 1][j]; // 不选i的情况
      if (j >= v[i])  f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]); // 选i的请//况
    }
  }
  cout << f[n][m] << endl;
  return 0;
}

1.3 一维

1.3.1 一维思路讲解

      就是在二维思路的基础上将数据压缩为一维,如何压缩呢?就是将第i层不要,就是这种数据类似于滚动数组的概念,只需要很少的数组来实现循环。

1.3.2 一维思路代码实现

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
 
const int N = 1010;
int n, m;
int v[N], w[N];
int f[N];
 
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++)  cin >> v[i] >> w[i];
    for(int i = 1; i <= n; i++)
    {
        // 因为在实现中,我所需要的是前一层的数据
        for(int j = m; j >= v[i]; j--)
        {
            f[j] = max(f[j], f[j - v[i]] + w[i]);
        }
    }
    cout << f[m] << endl;
    return 0;
}

二、完全背包问题(链接

2.1 问题描述

2.2 二维

2.2.1 二维思路讲解(朴素做法)

      完全背包与01背包不一样的是:完全背包中的物品都可以无限次的取,而01背包中的物品只可以取一次,所以完全背包问题中的集合划分会比01背包问题的集合划分多的多的多。还是老方法,画出状态表示和状态计算。

      前面思路与01背包问题大差不差,只有在集合划分与01背包不同。这个物品也不是无限次的选取,而是在选出物品的总体积不超过背包的总容量。在朴素做法中,我们是将选取的方案用循环表示,即三重循环。

2.2.2 二维思路代码实现(朴素做法)

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
 
const int N = 1010;
int n, m;
int v[N], w[N];
int f[N][N];
 
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++)  cin >> v[i] >> w[i];
    for(int i = 1; i <= n; i++)
    {
        for(int j = 0; j <= m; j++)
        {
            for(int k = 0; k * v[i] <= j; k++)
            {
                f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);
            }
        }
    }
    cout << f[n][m] << endl;
    return 0;
}

2.3 优化版本

2.3.1 优化版本思路讲解

      我们可以发现一个规律:就是我们如果写出将j减去v[i]的话,与f[i][j]之间的关系:f[i][j] = max(f[i - 1][j], f[i - 1][j - v] + w, f[i - 1][j - k*v] + k*w……f[i - 1][j - s*v] + s*w)(其中s*v小于等于m),那么f[i][j - v] = max(f[i - 1][j - v] + w, f[i - 1][j - k*v] + k*w……f[i - 1][j - s*v] + s*w)(其中s*v小于等于m)。总结上述的式子,我们可以发现f[i][j] = max(f[i - 1][j], f[i][j - v] + w)。

2.3.2 优化版本代码实现

 一维写法
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
 
const int N = 1010;
int n, m;
int v[N], w[N];
int f[N];
 
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++)  cin >> v[i] >> w[i];
    for(int i = 1; i <= n; i++)
    {
        for(int j = v[i]; j <= m; j++)
        {
            f[j] = max(f[j], f[j - v[i]] + w[i]);
        }
    }
    cout << f[m] << endl;
    return 0;
}

总结问题/注意事项

相关文章
|
传感器 数据采集 存储
ARM Linux摄像头传感器数据处理全景视野:从板端编码视频到高级应用(一)
ARM Linux摄像头传感器数据处理全景视野:从板端编码视频到高级应用
519 0
|
消息中间件 存储 数据可视化
kafka高可用集群搭建
kafka高可用集群搭建
337 0
|
监控 Java Nacos
微服务轮子项目(02) - 框架技术选型
微服务轮子项目(02) - 框架技术选型
262 0
|
2月前
|
移动开发 小程序 前端开发
小程序开发平台有哪些?哪个好
小程序的开发方式丰富多元,开发团队可根据自身的技术背景、项目具体需求以及资源状况,灵活挑选最为适宜的开发路径。以下将详细介绍几种主流的小程序开发方式。
351 1
|
12月前
|
缓存 网络协议 安全
融合DNS技术产品和生态
本文介绍了阿里云在互联网基础资源领域的最新进展和解决方案,重点围绕共筑韧性寻址、赋能新质生产展开。随着应用规模的增长,基础服务的韧性变得尤为重要。阿里云作为互联网资源的践行者,致力于推动互联网基础资源技术研究和自主创新,打造更韧性的寻址基础服务。文章还详细介绍了浙江省IPv6创新实验室的成立背景与工作进展,以及阿里云在IPv6规模化部署、DNS产品能力升级等方面的成果。此外,阿里云通过端云融合场景下的企业级DNS服务,帮助企业构建稳定安全的DNS系统,确保企业在数字世界中的稳定运行。最后,文章强调了全链路极致高可用的企业DNS解决方案,为全球互联网基础资源的创新提供了中国标准和数字化解决方案。
|
关系型数据库 MySQL 数据安全/隐私保护
windows mysql8 安装后 提示密码不对,修改下密码认证方式就可以了
windows mysql8 安装后 提示密码不对,修改下密码认证方式就可以了
2600 3
|
人工智能 自然语言处理 文字识别
秒懂全文:盘点13个各具特色的AI智能阅读助手工具
在当今信息爆炸的时代,AI阅读工具正在革新我们的阅读方式,成为了提高效率、优化阅读体验的关键。这类AI阅读辅助工具,只需要上传文件或者输入链接,便可以直接以聊天对话的形式进行一键总结和智能问答,满足用户AI PDF 阅读、AI文档问答分析、AI音视频总结等多种实用需求,高效提炼信息要点精华,建立属于自己的AI知识管理和信息管理工作流。对此,根据阅读场景,精选了 13 个具有代表性、各具特点的高质量 AI 阅读助手助理。 具体如何选择,见文末总结。
2306 1
秒懂全文:盘点13个各具特色的AI智能阅读助手工具
|
人工智能 算法 JavaScript
无界SaaS与AI算力算法,链接裂变万企万商万物互联
本文介绍了一种基于无界SaaS与AI算力算法的商业模式的技术实现方案,涵盖前端、后端、数据库及AI算法等关键部分。通过React.js构建用户界面,Node.js与Express搭建后端服务,MongoDB存储数据,TensorFlow实现AI功能。提供了项目结构、代码示例及部署建议,强调了安全性、可扩展性和性能优化的重要性。
|
安全 前端开发 中间件
Python面试题:Django Web框架基础与进阶
【4月更文挑战第17天】本文详细梳理了Django面试中常考的基础和进阶问题,包括MTV架构、ORM、数据库迁移、视图模板、中间件、信号、表单验证、用户认证授权等,并指出易错点及规避策略。提供代码示例展示模型和视图的实现,助力开发者在面试中脱颖而出。
814 12
|
存储 安全 网络协议
邮件协议揭秘:SMTP与IMAP的双重功能解析
SMTP和IMAP是电子邮件系统的核心协议,SMTP负责邮件发送,通过SSL/TLS保证安全,而IMAP则处理邮件接收和管理,支持服务器存储及状态同步。这两种协议相辅相成,为现代邮件系统提供了坚实基础。它们广泛应用于各种邮件客户端,确保了兼容性、功能丰富性和安全性,满足用户对电子邮件的多样化需求。
925 3

热门文章

最新文章