首页 > 编程语言 >代码随想录算法训练营第三十三天| 01背包问题 二维 01背包问题 一维 416. 分割等和子集

代码随想录算法训练营第三十三天| 01背包问题 二维 01背包问题 一维 416. 分割等和子集

时间:2023-07-18 15:33:08浏览次数:48  
标签:vector 01 20 weight 容量 随想录 背包 物品 dp

01背包问题 二维

 要求:

有一个背包,他只能装4KG,分别有三个物品: 1 15;3 20; 4 30 ——》需要物品价值最大 

dp[i][j] 含义:

在放物品I 的时候在J背包容量下的物品最大值

递推公式: 

1,不放当前物品:dp[i-1][j]
2,放当前物品:(dp[i-1][j]) ->不应该是在当前容量下,i-1的最大价值,应该是:dp[i-1][j-weight[i]] 如果i 要3KG,那么就是i-1在1KG 下的最大值

初始化:

1,容量为0时,全为0,
2,物品0 对于J来说如果容量大于,那么就是value[0],否则为0

 测试代码:

// vector<int> weight = {1, 3, 4};
// vector<int> value = { 15, 20, 30 };
// int bagweight = 4;

代码:

 1 // 01背包问题
 2 // 要求:有一个背包,他只能装4KG,分别有三个物品: 1 15;3 20; 4 30 ——》需要物品价值最大
 3 // dp[i][j] 含义:在放物品I 的时候在J背包容量下的物品最大值
 4 // 
 5 // 递推公式: ——》疑问,如果放当前物品,但是其实不放,放下一个才是最大值,这是怎么实现的,也就是如何实现多个解,然后选择最大值?
 6 //    1,不放当前物品:dp[i-1][j]
 7 //    2,放当前物品:(dp[i-1][j]) ->不应该是在当前容量下,i-1的最大价值,应该是:dp[i-1][j-weight[i]] 如果i 要3KG,那么就是i-1在1KG 下的最大值
 8 // 
 9 // 初始化:
10 //    1,容量为0时,全为0,
11 //  2,物品0 对于J来说如果容量大于,那么就是value[0],否则为0
12 // 
13 // 测试代码:
14 //   vector<int> weight = {1, 3, 4};
15 //   vector<int> value = { 15, 20, 30 };
16 //     int bagweight = 4;
17 //
18 int test_2_wei_bag_problem1(vector<int>& weight, vector<int> &value, int& bagweight)
19 {
20     vector<vector<int>> dp(weight.size(), vector<int>(bagweight+1, 0));
21 
22     for (int i = 0; i <= bagweight; i++)
23     {
24         if (weight[0] <= i)
25         {
26             dp[0][i] = value[0];
27         }
28     }
29 
30     for (int i = 1; i < dp.size(); i++)
31     {
32         for (int j = 0; i <= bagweight; j++)
33         {
34             if (bagweight < weight[i])
35             {
36                 dp[i][j] = dp[i - 1][j];
37                 continue;
38             }
39 
40             int cur1 = dp[i - 1][j];
41             int cur2 = value[i] + dp[i - 1][j - weight[i]];
42 
43             dp[i][j] = max(cur1, cur2);
44         }
45     }
46 
47     int result = INT_MIN;
48     for (int i = 0; i < dp.size(); i++)
49     {
50         if (result < dp[i][bagweight])
51         {
52             result = dp[i][bagweight];
53         }
54     }
55 
56     return result;
57 }
 

 01背包问题 一维 

dp[J]:

当容量为 J 的时候的最大值

递推公式:

// J : 当前容量 I:当前物品
// 1,不放当前物品:dp[J] = dp[J]
// 2,放当前物品: dp[J] = dp[J - weight[I]] + value[I] 

初始化:

// 1,dp[o] = 0

遍历顺序:

// 设想当容量为1的时候放了一个A,容量为2的时候再放了物品A dp[1] = 20 dp[2] = dp[1]+20 = 40
// 如果dp[i][j]
// dp[A][1] ; dp[B][2] = dp[A][1]+B 而不是加A
// 理想的情况:dp[1] 放了物品A,那么dp[2] 的时候就不要再放物品A了
// 因为每次是针对单个容量来搞的,并不代表和dp[0]有任何联动?——》不正确
// 先看物品A, 然后让容量从高到底来做,——》这样和dp[i-1] 有关系么? ——》 有关系,可以看下面
// 可以保证A在每个容量里只放了依次
// 当下一个容量的时候,就可以用上一个物品了

代码 

 1 // 使用一个一维数组 来搞动态规划
 2 // dp[J]:当容量为 J 的时候的最大值
 3 // 递推公式:
 4 //  J : 当前容量 I:当前物品
 5 //    1,不放当前物品:dp[J] = dp[J]
 6 //    2,放当前物品: dp[J] = dp[J - weight[I]] + value[I]
 7 // 
 8 // 初始化:
 9 //    1,dp[o] = 0
10 // 遍历顺序:
11 // 设想当容量为1的时候放了一个A,容量为2的时候再放了物品A dp[1] = 20  dp[2] = dp[1]+20 = 40
12 // 如果dp[i][j]
13 //    dp[A][1] ; dp[B][2] = dp[A][1]+B 而不是加A
14 // 
15 // 理想的情况:dp[1] 放了物品A,那么dp[2] 的时候就不要再放物品A了
16 // 因为每次是针对单个容量来搞的,并不代表和dp[0]有任何联动?——》不正确
17 // 先看物品A, 然后让容量从高到底来做,——》这样和dp[i-1] 有关系么? ——》 有关系,可以看下面
18 //    可以保证A在每个容量里只放了依次
19 // 当下一个容量的时候,就可以用上一个物品了
20 //
21 int test_1_wei_bag_problem(vector<int>& weight, vector<int>& value, int& bagweight) 
22 {
23     vector<int> dp(bagweight + 1, 0);
24 
25     for (int i = 0; i < weight.size(); i++)
26     {
27         for (int j = bagweight; j >= 0; j--)
28         {
29             if (j < weight[i])
30             {
31                 continue;
32             }
33             else 
34             {
35                 dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
36             }        
37         }
38     }
39 
40     return dp[bagweight];
41 }

 



标签:vector,01,20,weight,容量,随想录,背包,物品,dp
From: https://www.cnblogs.com/smartisn/p/17563153.html

相关文章

  • Oracle 主键冲突报错踩坑-- "ORA-00001: 违反唯一约束条件 "
    根本原因因为特殊字符存在导致的主键冲突报错细节分析前提oracle中存在一张table,table中存在字段CName(nvarchar),且该字段为唯一主键;具体现有一条数据需要入库,内容如下'中信建投惠享债券型证券投资基金​'(包含零宽空格符)直接根据这个字段值查询数据库值是不存在的sel......
  • [GUET-CTF2019]KO
    直接给了一个txt文件,打开直接是ook的编码不知道为啥在随波上面直接用brainfuck就直接出来又用了一下ook的解码网站也是一样的网址:Brainfuck/Ook!Obfuscation/Encoding[splitbrain.org]结束......
  • 远程登陆virtualbox虚拟机windows server 2019
    1.virtualbox网络设置2.启用远程桌面3.获取远程ip4.本机使用mstsc远程登陆......
  • LeetCode 301. 删除无效的括号
    classSolution{public:vector<string>ans;vector<string>removeInvalidParentheses(strings){//lr分别记录要删除的左右括号数量intl=0,r=0;for(autoc:s)if(c=='(')l++;elseif(c=='......
  • [GXYCTF2019]Ping Ping Ping
    [GXYCTF2019]PingPingPing题目来源:buuctf题目类型:web涉及考点:命令执行1.题目页面如下:我们将其作为参数传入,/?ip=127.0.0.1,回显如下:接下来通过命令行查看目录:/?ip=127.0.0.1;ls2.发现了flag.php,直接查看/?ip=127.0.0.1;catflag.php发现空格被过滤了,我们采取以下......
  • [HNOI2012] 集合选数
    [HNOI2012]集合选数目录题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示题意概括思路历程:1.设计状态2.设计转移代码实现:题目描述《集合论与图论》这门课程有一道作业题,要求同学们求出\(\{1,2,3,4,5\}\)的所有满足以下条件的子集:若\(x\)在该子集中,则\(2......
  • 01-TienChin-系统功能介绍
    title:01-TienChin-系统功能介绍date:2023-7-1723:02:10tags:-TienChin业务功能线索管理添加线索查看线索删除线索修改线索分配线索:​将录入到系统的线索,分配给某一个市场专员去处理跟进线索:​持续跟进一条线索1.判断是否伪线索2.持续跟进,每次跟进需要......
  • 【2023.07.14】Atcoder:past201912 - 第一回 アルゴリズム実技検定(div4+区域赛难度)过题
    G-Division解法一:位运算+状压枚举(赛时思路)范围显然,可以跑\(2^n\)的算法,考虑位运算状态压缩。以\(\mathcalO(2^n\cdot2^n)\)的复杂度分别枚举位于第一组、第二组中的人,随后计算每一种分组的快乐值,代码较长,赛时敲了半个小时,不过好在一发过了。总结:其实代码里面的剪枝完......
  • [强网杯 2019]随便注
    [强网杯2019]随便注题目来源:buuctf题目类型:web涉及考点:SQL注入、堆叠注入1.先简单介绍一下堆叠注入在SQL语句中,分号用来表示一条语句的结束。那么当我们结束一条语句之后,继续构造下一条语句,可不可以一起执行呢?这就是堆叠注入,简单来说,就是把多条SQL语句一起上传。例如,我们......
  • 01分数规划
    01分数规划属于二分法的一个应用,主要用于解决有关“最优比率”的问题,如最优比率背包、最优比率生成树等。题目大致是说,给定两个长度均为\(n\)的数组\(a、b\),要从中选出\(k\)组\(a\)和\(b\),求\(max\dfrac{\sum_{i=1}^na_is_i}{\sum_{i=1}^nb_is_i}\)。其中\(s_i=0\)(......