当前位置: 首页 > article >正文

01背包入门讲解

01背包问题研究的是,给定n件物品以及能够最大承重为maxWeight的背包,第i个物品的重量为item[i].weight,价值为item[i].value.每一件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大?

dp[i][j]含义

根据题干可知,最后的答案dp[n-1][maxWeight](i下标从0开始)表示求解将n件物品任取放入最大承重为maxWeight的背包,求背包物品的最大价值,因此可知dp[i][j]应该表示将从0~i物品中任取放入最大承重为j的背包里面,求其背包物品的最大价值。

递推公式

下求dp[i][j]的递推公式,由于第i件物品是否放入背包仅仅两种情况:不放与放。

先讨论第i件物品不放入背包的情况,易知,当第i件物品不放入最大承重为j的背包时,背包的价值最大,那么其价值dp[i][j]等于将0~i-1件物品放入最大承重为j的背包时,背包的最大价值dp[i-1][j],

即dp[i][j]=dp[i-1][j]

再讨论第i件物品放入背包的情况,易知,当第i将物品放入最大承重为j的背包时,背包的价值最大,那么其价值dp[i][j]等于0~i-1件物品放入承重为j-item[i].weight的背包时,背包的最大价值dp[i-1][j-item[i].weight]加上第i个物品的价值item[i].value,

即dp[i][j]=dp[i-1][j-item[i].weight]+item[i].value

解释第二种情况,由于唯有从0~i-1件物品任取放入最大承重为j-item[i].weight的背包加上第i件物品的重量才能使新背包的最大承重为j,故dp[i][j]=dp[i-1][j-item[i].weight]+item[i].value

因此,dp[i][j]的递推公式为:

dp[i][j]=max(dp[i-1][j],dp[i]-1[j-item[i].weight]+item[i].value)

dp数组的初始状态

(图片来自代码随想录)

根据上述推导公式可知,dp[i][j]由其上方左上方的元素推导而来,因此需要初始化数组中最上一行以及最左一行的元素。

显然,dp[i][0]=0表示最大承重为0的背包的最大价值为0dp[0][j]表示第0个物品装入最大承重为j的背包的物品最大价值。易知,当item[0].weight>=j时,dp[0][j]=item[0].value;否则,dp[0][j]=0.

遍历数组

利用二重循环,物品从第1件物品开始,背包最大承重j从1开始,递推数组的元素dp[i][j],最终输出dp[n-1][maxWeight].

代码实现

语言:c++,环境:Visual Studio 2022

#include<iostream>
using namespace std;
typedef struct Item {
    int weight;
    int value;
}Item;

Item item[1007];
int dp[1007][1007];
int maxWeight,n;

int main() {
    cin >> n >> maxWeight;
    if (n >= 1007 || maxWeight >= 1006) {
        return 0;
    }
    for (int i = 0;i < n;i++) {
        cin >> item[i].weight >> item[i].value;
    }
    //初始化,dp[0][j]
    for (int i = 0;i <= maxWeight;i++) {
        if (i >= item[0].weight) {
            dp[0][i] = item[0].value;
        }
    }
    //遍历数组
    for (int i = 1;i < n;i++) {
        for (int j = 1;j <= maxWeight;j++) {
            if (j - item[i].weight >= 0) {
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - item[i].weight] + item[i].value);
            }
            else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }
    cout << dp[n - 1][maxWeight] << endl;
    return 0;
}

结束!


http://www.kler.cn/a/329.html

相关文章:

  • 基于Pycharm与数据库的新闻管理系统(3)MongoDB
  • ShenNiusModularity项目源码学习(6:访问控制)
  • Spring自动化创建脚本-解放繁琐的初始化配置!!!(自动化SSM整合)
  • XXE漏洞 黑盒测试 白盒测试 有无回显问题
  • 如何删除Mac上的系统数据
  • Numpy指南:解锁Python多维数组与矩阵运算(下)
  • 程序员的逆向思维
  • AcWing算法基础课笔记 第一章 基础算法
  • 【数据结构】链表OJ(二)
  • 测试背锅侠?入职软件测试后大d佬给我丢了这个bug分类分析,至今受益匪浅......
  • 实现异步的8种方式,你知道几个?
  • 二叉树习题
  • 【蓝桥杯-筑基篇】常用API 运用(1)
  • 【c++】继承
  • 自学大数据第六天~HDFS命令(一)
  • Linux基础命令大全(下)
  • python+django+vue图书个性化推荐系统
  • Vue3之父子组件通过事件通信
  • 高速PCB设计指南系列(四)
  • Java for循环嵌套for循环,你需要懂的代码性能优化技巧
  • 常见的HTTP状态码
  • HTTP 3.0来了,UDP取代TCP成为基础协议,TCP究竟输在哪里?
  • 滑动窗口算法
  • CentOS定时任务——crontab
  • Vue 3.0 单文件组件 【Vue3 从零开始】
  • 猿人学爬虫第1题- js混滑–源码乱码