首页 > 其他分享 >01背包

01背包

时间:2024-03-24 21:24:54浏览次数:22  
标签:01 int 二维 背包 数组 物品 遍历

0/1背包二维形式

二维数组 f[][] 被用作动态规划的辅助数组,它的作用是存储在不同的背包容量和不同的物品选取情况下所能达到的最大总价值。

具体来说,f[i][j] 表示在前 i 个物品中选取,并且背包容量限制为 j 时所能达到的最大总价值。

在动态规划的过程中,f[i][j] 的计算依赖于前一行 f[i - 1][j] 和可能的另一项 f[i - 1][j - v[i]] + w[i]。其中 f[i - 1][j] 表示不选择当前物品 i 的情况下的最大价值,而 f[i - 1][j - v[i]] + w[i] 表示选择当前物品 i 后的最大价值。通过比较这两种情况的价值,更新 f[i][j] 为较大的那个值,从而不断地填充 f[][] 数组,直到计算得到 f[n][m],即前 n 个物品在背包容量为 m 时的最大总价值。

因此,f[][] 数组在这里扮演了记录子问题最优解的角色,通过填充这个数组,最终可以得到原问题的最优解。

#include<iostream>
#include<algorithm>
using namespace std;

const int N = 1010; // 定义常量 N,值为 1010
int v[N], w[N]; // 声明数组 v 和 w,用于存储物品的价值和重量
int f[N][N]; // 声明二维数组 f,用于动态规划

int main()
{
    int n, m;
    cin >> n >> m; // 读取物品数量 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++) // 对于每种可能的重量
        {
            f[i][j] = f[i - 1][j]; // 默认情况下,不选择当前物品 i

            // 如果当前重量可以容纳物品 i,则考虑选择物品 i 的情况
            if (j >= v[i])
                f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
        }

    cout << f[n][m] << endl; // 输出最大价值
    return 0;
}

0/1背包一维形式

将二维形式的动态规划转换为一维形式的关键在于重新设计状态转移方程,并且利用一维数组来存储中间状态。下面是从二维形式到一维形式的转换步骤:

  1. 重新定义状态

    • 在二维形式中,状态 f[i][j] 表示在前 i 个物品中选取,并且背包容量限制为 j 时所能达到的最大总价值。
    • 在一维形式中,我们需要重新定义状态,令 f[j] 表示背包在容量为 j 时所能达到的最大总价值。
  2. 更新状态转移方程

    • 在二维形式中,状态转移方程为:f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i])
    • 我们需要重新设计状态转移方程,以便在一维数组中更新 f[j]。观察二维形式的转移方程,可以发现 f[i][j] 的更新只与 f[i - 1][j]f[i - 1][j - v[i]] 相关。因此,我们可以将状态转移方程改写为:f[j] = max(f[j], f[j - v[i]] + w[i])
  3. 适当修改遍历顺序

    • 在二维形式中,我们使用了两个循环,其中外循环遍历物品,内循环遍历背包容量。
    • 在一维形式中,我们只需要一个循环来遍历物品,并且通过逆序遍历背包容量,以确保每次更新 f[j] 时所需的 f[j - v[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]);
        }
    }
    
    

    在这段代码中,我们只使用了一个循环来遍历物品,通过逆序遍历背包容量,从而确保每次更新 f[j] 时所需的 f[j - v[i]] 是上一轮循环的值。

#include<iostream>
#include<algorithm>
using namespace std;

const int N = 1010; // 定义常量 N,值为 1010
int v[N], w[N]; // 声明数组 v 和 w,用于存储物品的价值和重量
int f[N]; // 声明数组 f,用于存储背包在不同容量下的最大总价值

int main()
{
    int n, m;
    cin >> n >> m; // 读取物品数量 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--) // 对于每种可能的背包容量(逆序遍历)
        {
            // 考虑选取当前物品 i 的情况,更新背包容量为 j 时的最大总价值
            f[j] = max(f[j], f[j - v[i]] + w[i]);
        }

    cout << f[m] << endl; // 输出背包容量为 m 时的最大总价值
    return 0;
}

标签:01,int,二维,背包,数组,物品,遍历
From: https://www.cnblogs.com/KAI040522/p/18093082

相关文章

  • P5324 [BJOI2019] 删数
    P5324[BJOI2019]删数转化条件+线段树由于值域不大,并且删数操作跟序列顺序无关,只和每个数的出现次数有关,考虑在值域上分析删数操作。发现对于每一个值\(i\)可以抽象为覆盖了\([i-buc_{i}+1,i]\)的区间。要使数列删空,就要让\([1,n]\)被填满。这样我们就会发现答案就是\([......
  • RabbitMQ3.x之一_WindowServer2019中安装RabbitMQ详细教程
    RabbitMQ3.x之一_WindowServer2019中安装RabbitMQ详细教程文章目录RabbitMQ3.x之一_WindowServer2019中安装RabbitMQ详细教程1.安装环境说明1.WindowServer20192.ErLang与RabbitMQ对应版本2安装Erlang1.安装Erlang2.ErLnag环境变量配置3.查看是否安装成功3.安......
  • 2019 年互联网寒冬下IT程序员招聘行情招聘形势感受
        几次听到过一个段子:2019年可能会是过去10年里最差的一年,但却是未来10年里最好的一年。前不久在清华大学上课的时候我们一个教授(他参与当前国家经济政策制定的)也善意提醒我们未来几年花钱一定要紧,切勿乱投资。虽然这些说法或许有些过于绝对和悲观,但春江水暖鸭先知,相信说......
  • windows server2012安装百度云网盘导致内存溢出
    步骤首先需要下载软件shexview,一款免费的软件,用于查看Windows资源管理器安装的插件。下载地址https://www.nirsoft.net/utils/shexview-x64.zip下载后解压运行shexview.exe: 打开能看到Windows资源管理器安装的插件,可以看到我已经将所有百度网盘的插件全部禁用掉了。 ......
  • P10111 [GESP202312 七级] 纸牌游戏 题解
    看标签知道要用DP。于是开始分析。状态:$dp(i,j,k)=$前\(i\)轮中,第\(i\)轮出\(j\),一共换了\(k\)次牌的最大钱数。很好理解。转移也不难,不就是不换和换两种吗!所以,转移就是:\[dp(i,j,k)=\max\begin{cases}dp(i-1,j,k)+\operatorname{pk}(j,c_i)\times......
  • 【动态规划】【同余前缀和】【多重背包】[推荐]2902. 和带限制的子多重集合的数目
    本文涉及知识点动态规划汇总C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例包括课程视频C++算法:滑动窗口总结多重背包LeetCode2902.和带限制的子多重集合的数目给你一个下标从0开始的非负整数数组nums和两个整数l和r。请你返回nums中子多重集......
  • Adobe的PDF编辑软件Acrobat Pro DC 2024.001.20604版本下载与安装教程
    目录前言一、AcrobatProDC2024安装二、使用配置总结前言PDF格式(缩写为便携式文档格式和便携式文档格式)的发展始于1990年。这种格式用于以类似于打印文档的固定格式呈现包含文本、图像和其他要求的文档。Adobe在1993年发布了专有的Acrobat软件,首次展示了对这种......
  • 洛谷之P1563 [NOIP2016 提高组] 玩具谜题
    题目 [NOIP2016提高组]玩具谜题题目背景NOIP2016提高组D1T1 题目描述小南有一套可爱的玩具小人,它们各有不同的职业。有一天,这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。如下图: 这时singer告诉小南一个谜......
  • 安装Visual Studio2015后找不到C++项目模板解决办法
    安装VisualStudio2015后找不到C++项目模板解决办法:方法1:您可以通过修改VisualStudio来完成此操作,并且可以使用以下步骤完成此操作:1、转到“添加或删除程序”对话框中的“控制面板”;2、选择要修复的产品,然后单击“安装向导”,单击“Next;3、单击“repair。方法2:您可以通过以下......
  • 蓝桥杯2017年第八届真题-分巧克力(二分算法)
    题目描述儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。小明一共有N块巧克力,其中第i块是HixWi的方格组成的长方形。为了公平起见,小明需要从这N块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:1.形状是正方形,边长是整数2.大......