156、【动态规划】AcWing ——3. 完全背包问题:二维数组+一维滚动数组(C++版本)

news/2024/6/16 8:34:44 标签: 动态规划, c++, 算法

题目描述

在这里插入图片描述
在这里插入图片描述
原题链接:3. 完全背包问题

解题思路

完全背包相对于01背包来说,对同一个物品可以选择多次。而01背包对同一个物品只能选择一次。

递推公式上的区别:01背包是dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]),完全背包是dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i])

(1)dp[i][j]二维数组

(1)dp[i][j]含义: 在背包容量为j的条件下,从0-i中选取物品,可达到的最大价值。

(2)递推公式: dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i]),该公式是由两个公式联立而成。
公式1:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i], dp[i - 1][j - 2*v[i]] + 2*w[i] + ... + dp[i - 1][j - n*v[i]] + n*w[i]),其中n*v[i]是刚好小于等于j。该公式是说明,在同一物品可多次选择的条件下,不选该物品和选择该物品时,取得一个最大价值的方案。
公式2:dp[i - 1][j - v[i]] + w[i]= max(dp[i - 1][j - v[i]], dp[i - 1][j - 2*v[i]] + w[i], dp[i - 1][j - n*v[i]] + (n-1)*w[i]) + w[i],是由公式1的逻辑演化而来。

(3)dp数组初始化: dp[i][0] = 0,容量为0时,价值为0。

(4)遍历顺序: 先背包再物品,或者先物品再背包都可以,顺序是从小到大。

(5)举例: (省略)

#include <iostream>

using namespace std;

const int N = 1010;
int dp[N][N];
int v[N], w[N];
int n, m;

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 = 1;j <= m; j++) {
            if(v[i] > j)        dp[i][j] = dp[i - 1][j];
            else                dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i]);
        }
    }
    
    cout << dp[n][m] << endl;
    
    return 0;
}

(2)d[j]一维滚动数组

(1)dp[j]含义: 在背包容量为j的条件下,从0-i中选取物品,可达到的最大价值。

(2)递推公式: dp[j] = max(dp[j], dp[j - v[i]] + w[i]),按照一定的遍历顺序要与二维中的公式等价。

(3)dp数组初始化: dp[0] = 0,容量为0时,价值为0。

(4)遍历顺序: 先背包再物品,或者先物品再背包都可以,顺序是从小到大,从而实现,在外层值固定时,内层for循环遍历过程中,可以加到之前已加上的数据信息。

(5)举例: (省略)

#include <iostream>

using namespace std;

const int N = 1010;
int dp[N];
int v[N], w[N];
int n, m;


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++) {
            // dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i])
            dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
        }
    }
    
    cout << dp[m] << endl;
    
    return 0;
    
}

http://www.niftyadmin.cn/n/59619.html

相关文章

操作系统(一): 进程和线程,进程的多种状态以及进程的调度算法

文章目录前言一、进程和线程1. 进程2. 线程二、进程和线程的区别(面试常问)三、进程调度算法3.1. 批处理系统3.2. 交互式系统3.2.1 时间片轮转3.2.2 优先级调度3.2.3 多级别反馈队列3.3. 实时系统四、进程的状态五、进程同步5.1 什么是进程同步5.2 进程同步应该遵循的几点原则前…

十二、GSettings

介绍 GSettings类提供了一个方便的API来存储和检索应用程序设置。 读写可以被认为是非阻塞的。使用GSettings读取设置通常是非常快的:在大致相同的数量级上(但比)GHashTable查找要慢。写入设置在返回应用程序的时间方面也非常快&#xff0c;但对于其他线程和其他进程来说可能…

Java:SpringMVC的使用(2)

目录第十二章 REST风格CRUD练习12.1 搭建环境12.2 实现功能思路第十三章 SpringMVC消息转换器13.1 消息转换器概述13.2 使用消息转换器处理请求报文(1) 使用RequestBody获取请求体(2) 使用HttpEntity\<T>获取请求体及请求头13.3 使用消息转换器处理响应报文(1) 使用Respo…

基于javaee的电影碟片租赁管理系统的设计

技术&#xff1a;Java、JSP、框架等摘要&#xff1a;随着信息技术在管理中的广泛应用&#xff0c;管理信息系统(MIS)的实施在技术上逐渐成熟。为了适应时代的发展&#xff0c;降低管理成本&#xff0c;提高工作效率&#xff0c;企业需要加强对内部资源(人、钱、物)的有效管理&a…

微前端-模块联邦

一、 Module Federation 模块联邦概述 Module Federation 即为模块联邦&#xff0c;是 Webpack 5 中新增的一项功能&#xff0c;可以实现跨应用共享模块。 二、快速上手 需求 通过模块联邦在容器应用中加载微应用。 应用结构 products ├── package-lock.json ├──…

windbg-应用层实时调试

调试符号windbg使用一个或多个目录来存放符号条件&#xff0c;并使用环境变量_NT_SYMBOL_PATH来指向这些环境变量的位置&#xff0c;对操作系统内部模块的符号文件&#xff0c;一般用http://msdl.microsoft.com/download/symbols配置如下&#xff1a;SRV*C:\Symbols*http://msd…

自动机,即有限状态机

文章目录一、问题来源二、题目描述三、题解中的自动机四、自动机学习五、有限状态机的使用场景一、问题来源 今天做力克题目的时候看到了字符串转换整数的一道算法题&#xff0c;其中又看到了题解中有自动机的概念&#xff0c;所以在这里对自动机做个笔记。题目链接 二、题目描…

Linux Vim编辑器基础讲解

目录 vim三个模式 命令模式 输入模式&#xff08;insert 插入模式、编辑模式&#xff09; 末行模式 编辑简单文档 什么是vim Vim是文本编辑器&#xff0c;是Linux上最常用的文本编辑器 Vim可以建立、编辑、显示文件 绝大多数Linux都会携带vim或者vi vim编辑器和vi编辑器的…