【第二十五课】动态规划:完全背包问题(acwing-3 / 公式推导 / 思路理解 / 优化 / c++代码)

这篇具有很好参考价值的文章主要介绍了【第二十五课】动态规划:完全背包问题(acwing-3 / 公式推导 / 思路理解 / 优化 / c++代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

思路

朴素代码

优化

公式推导上 

二维代码 

一维代码

公式理解上


 

在开始看完全背包问题之前,可能需要先了解01背包及其解决办法。 指路👇

【第二十五课】动态规划:01背包问题(acwing-2 / 思路 / 含一维数组优化 / c++代码)

【第二十五课】动态规划:完全背包问题(acwing-3 / 公式推导 / 思路理解 / 优化 / c++代码),算法--学习笔记,动态规划,算法,c++

思路

这个问题和01背包的区别就是每件物品可以选无限次(当然在背包容量限制之内)

也就是说,01背包中我们在面对第i件物品的时候,有两种选择,分别是:选和不选,也就是第 i 件物品选择0次和1次,而完全背包也就是说,我们可选择的选项变多了,我们可以选择第i件物品 0,1,2,3,......k次,也就是在01背包分析问题方法的基础上,做了一点变化,如图

【第二十五课】动态规划:完全背包问题(acwing-3 / 公式推导 / 思路理解 / 优化 / c++代码),算法--学习笔记,动态规划,算法,c++

如果仅仅是这里发生了改变的话,其实我们在不考虑优化情况下,最朴素的写法应该是很容易得出的。

状态转移方程变为:dp[i][j]=max(dp[i-1][j],dp[i-1][j-k*v[i]]+k*w[i]) 

都是为了填充这个二维数组,只不过把选择从0和1两个变成了0-k个

朴素代码

#include<iostream>
using namespace std;
const int N=1010;
int n,m;
int v[N],w[N];
int dp[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++)
            {
                dp[i][j]=max(dp[i][j],dp[i-1][j-k*v[i]]+k*w[i]);
            }
        }
    }
    cout<<dp[n][m];
    return 0;
}

这种写法应该可以理解。

但是我们也看到了嵌套了三层循环。因此我们想着对他进行优化

优化

公式推导上 

经过上面的分析我们知道完全与01背包问题的区别就是选择这件物品的次数,那么我们想试着用01背包的状态转移方程来写完全背包的,观察一下有没有什么规律,能够简化一层循环的。

下面图中是关于公式推导的过程 

【第二十五课】动态规划:完全背包问题(acwing-3 / 公式推导 / 思路理解 / 优化 / c++代码),算法--学习笔记,动态规划,算法,c++

下面这个视频老师讲了具体的公式推导的过程,也对二维数组的填充过程给出了呈现,非常详细,推荐看一下帮助理解二维的写法。(可以倍速观看)

 【叶老师讲信奥--完全背包问题】

下面这个老师是按照公式推导变化的方式进行讲解的,也很清晰,推荐看一下。

【完全背包问题求解-NOIP/CSP/蓝桥杯算法试学课-青少年C++编程】

二维代码 

#include<iostream>
using namespace std;
const int N=1010;
int n,m;
int v[N],w[N];
int dp[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++)
        {
            dp[i][j]=dp[i-1][j];
            if(j>=v[i])dp[i][j]=max(dp[i][j],dp[i][j-v[i]]+w[i]);
        }
    }
    cout<<dp[n][m];
    return 0;
}

一维代码

#include<iostream>
using namespace std;
const int N=1010;
int n,m;
int v[N],w[N];
int dp[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++)
        {
            dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
        }
    }
    cout<<dp[m];
    return 0;
}

公式理解上

如果不看公式推导,单纯考虑公式的理解方面来说,我们发现状态转移方程从

dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]) 这样,转变为

-

dp[i][j] = max(dp[i][j], dp[i][j - v[i]] + w[i]) 这样

我们直观来看,其实后者也就是在第二个部分从i-1变成了i 。01背包问题我们是如何理解这个i-1的?也就是从第i行的前一行得出这一行的结果。那么这里变成了 i ,也就是说,我们本行的结果,就是通过本行的数据来得出的。为什么?就因为一件物品可以被选多次

我们想一下在01背包的一维数组优化里,我们说需要逆序遍历,是因为我们要用上一层的数据,如果正序的话,我们一件物品就会被选多次,得到的就是更改之后的数据。那么按照这个想法,运用到完全背包问题里,正好就是解决完全背包的方法。因此完全背包的一维优化我们可以直接这样理解。

我之前会有疑惑,正序遍历所造成的一件物品选择多次,这个多次是否涵盖了完全背包问题的所有可能次数?会不会有漏掉的情况呢?

答案是不会的,我们每一次正序遍历都会尝试在当前容量下选择当前物品,直到背包容量不足以再选择当前物品为止。因此,正序遍历实际上已经尝试了所有可能的选择次数,不会有漏掉的情况。

细品hh~


好啦,完全背包写到这里。

有问题欢迎指出,一起加油!!文章来源地址https://www.toymoban.com/news/detail-841551.html

到了这里,关于【第二十五课】动态规划:完全背包问题(acwing-3 / 公式推导 / 思路理解 / 优化 / c++代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【动态规划之完全背包问题】完全背包问题的通用解法与优化

    ⭐️ 前面的话 ⭐️ 本篇文章将介绍动态规划中的背包问题——完全背包问题,前面我们已经介绍了0-1背包问题,其实完全背包问题就只改了0-1背包问题的一个条件,即物品可选择次数由一次改为无数次,仅此而已,下面我们就来开始介绍完全背包问题。 📒博客主页:未见

    2023年04月22日
    浏览(49)
  • 动态规划:完全背包问题

    ACwing #3. 完全背包问题 完全背包问题和01背包问题很相似。 01背包问题每个物品只能选一个,而完全背包问题每个物品可以选无限次。 DP问题的关键是找到状态转移方程: ①定义f[i][j]表示从前 i 个物品中选择,体积为 j 的时候的最大价值。 ②那么转移方程f[i][j] = max(f[i - 1][j

    2023年04月19日
    浏览(45)
  • 动态规划——完全背包问题

    由于本人实力尚浅,接触算法没多久,写这篇blog仅仅是想要提升自己对算法的理解,如果各位读者发现什么错误,恳请指正,希望和大家一起进步。(●’◡’●) 了解完全背包问题前可以先去看看01背包问题(良心正解),先了解这个基础问题会更有利于你了解下面的完全背

    2024年02月04日
    浏览(48)
  • 算法系列--动态规划--背包问题(3)--完全背包介绍

    💕\\\"Su7\\\"💕 作者:Lvzi 文章主要内容:算法系列–动态规划–背包问题(3)–完全背包介绍 大家好,今天为大家带来的是 算法系列--动态规划--背包问题(3)--完全背包介绍 链接: 完全背包 可以发现完全背包问题和01背包问题还是特比相似的 分析: 完全背包问题 是 01背包问题 的推广

    2024年04月25日
    浏览(45)
  • 动态规划完全背包问题-java

    完全背包问题跟01背包问题思路大致一样,只不过对于物品的拿取次数不在限制,我们只需要考虑这点即可。 文章目录 前言 一、什么是完全背包问题? 二、问题模拟 1.样例数据 2.算法思路 三、代码如下 1.代码如下(示例): 2.读入数 3.代码运行结果 总结 完全背包问题跟

    2024年04月26日
    浏览(44)
  • 动态规划-----背包类问题(0-1背包与完全背包)详解

    目录 什么是背包问题? 动态规划问题的一般解决办法: 0-1背包问题: 0 - 1背包类问题  分割等和子集:  完全背包问题:  完全背包类问题 零钱兑换II: 背包问题(Knapsack problem)是一种组合优化的NP完全问题。 问题可以描述为:给定一组物品,每种物品都有自己的重量和价格

    2024年04月17日
    浏览(35)
  • 三十八、动态规划——背包问题( 01 背包 + 完全背包 + 多重背包 + 分组背包 + 优化)

    0 1 背包问题: 条件:N 个物品容量为 V 的背包,每件物品最多用 1 次,其中物品信息体积为 Vi,价值为 Wi。 目标:选出物品,使价值最大(不一定装满背包)。 特点:每件物品 最多只用 1 次 完全背包问题: 特点:每一件物品都有 无限个 多重背包问题: 特点:每个物品

    2024年02月07日
    浏览(54)
  • 孩子都能学会的FPGA:第二十五课——用FPGA实现频率计

    (原创声明:该文是 作者的原创 ,面向对象是 FPGA入门者 ,后续会有进阶的高级教程。宗旨是 让每个想做FPGA的人轻松入门 , 作者不光让大家知其然,还要让大家知其所以然 !每个工程作者都搭建了全自动化的仿真环境,只需要双击 top_tb.bat 文件就可以完成整个的仿真(前

    2024年02月02日
    浏览(46)
  • 动态规划:完全背包问题----中专生刷算法

    需要基础:闫氏dp分析法,01背包问题 先去看一下01背包问题,再看完全背包 动态规划:选择dp及优化01背包问题-CSDN博客 做过01背包问题的同学会发现,完全背包问题的代码 在01背包基础上改动很小,但是里面的思想,有很大差距 题目 有 N 种物品和一个容量是 V的背包,每种物品

    2024年04月16日
    浏览(48)
  • 力扣刷题-动态规划算法3:完全背包问题

    问题描述: 1)有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。 2) 每件物品都有无限个(也就是可以放入背包多次) (比0-1背包多出的条件) 3) 求解将哪些物品装入背包里物品价值总和最大。 求解步骤: 1)首先遍历物品,然

    2023年04月13日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包