zoukankan      html  css  js  c++  java
  • 算法笔记----11.7.2 关于01背包的滚动数组

    前提摘要见上一篇

    01背包问题时间和空间复杂度都是O(nV), 空间复杂度可以继续优化为O(V)  算法笔记P444

    滚动数组代码

    1 dp[N];//这里只用一维的
    2 for(int i=1; i<=n; i++)//对每个数判断,可反
    3 {
    4         for(int j=m; j>=weight[i]; j--)/
    5             dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
    6 }

     

    这里用到还是熟悉的数据熟悉的内容:

    然后开始循环,先说下代码里面的n是物品,m是背包容量:,真实的值是n=6,m=12

    1)

    最初i=1,j=12表示只有1号物品也就是(4-8),背包容量为12时候。这时候dp[12]=max(dp[12],dp[12-4(1号物品体积)]+8(1号物品价值)])=8;

    这样一直到m[1][4]都是8,。当包容量小于此时1号物品容量时候跳出循环。

    这时候dp数组

    2)

    这是第二次n循环,这时候i=2,包含了一号物品(4-8)和二号物品(6-10) ;此时包可以装下

    dp[12]=max(dp[12],dp[12-6]+10)=dp[12-6]为8所以这dp[12]=18.同理dp[10]dp[11]都是18。

    dp[9]-dp[6]时候   比如max(dp[9],dp[9-6]+10)=dp[3]+10为10所以最终为10。

    这时候dp数组

    3)

    i=3, 包含了一号物品(4-8)和二号物品(6-10) 和三号物品(2-6),

    dp[12]=max(dp[12],dp[12-2]+6) = dp[12-2]+6 =24

    dp[11]=max(dp[11],dp[11-2]+6) = dp[11]=18

    dp[10]=max(dp[10],dp[10-2]+6) = dp[10] =18

    dp[9]=max(dp[9],dp[9-2]+6) = dp[7] +6 =16

    dp[8]=16

    dp[7] dp[6] =14

    dp[5] dp[4] = 8

    dp[3] = dp[1]+6 = 6

    dp[2]=6

     

     

    到这里气候就差不多了,下面都是类似的。

    看起来没什么问题了。

    不用滚动数组的话代码这样

    这就是上一次的数值。滚动数组是把它保留了然后从后往前更新,直到背包容量小于物品容量的话更新就不用了,直接拿上一次就好了。

     

     

    ps  如果第二个for正向遍历会怎样,也就是j从w[i]开始

    然后开始循环,先说下代码里面的n是物品,m是背包容量:,真实的值是n=6,m=12

    1)

    最初i=1,j=4开始 表示只有1号物品也就是(4-8),背包容量为12时候。这时候dp[4]=max(dp[4],dp[4-4(1号物品体积)]+8(1号物品价值)])=8;

    这样一直到m[1][7]都是8。

    然而dp[8]=max(dp[8],dp[8-4]+8) = d[4]+8 = 16

    同理d[12] = d[8]+8 =24

    这时候就变成完全背包问题了

    这时候dp数组

    0 0 0 0 8 8 8 8 16 16 16 16 24

    2)

    这是第二次n循环,这时候i=2, j=6开始,包含了一号物品(4-8)和二号物品(6-10) ;此时包可以装下

    dp[6]=max(dp[6],dp[6-6]+10)=dp[0]+10为10  所以这dp[6]=10. 同理dp[6]到dp[7]都是10。

    dp[8]=max(dp[8],dp[8-6]+10)=dp[8] = 第一步中16

    dp[9]=16

    dp[10] dp[11] =18

    dp[12] = max(dp[12],dp[12-6]+10)=dp[12]为24所以最终为24。  (就是完全背包问题

    这时候dp数组

    0 0 0 0 8 8 10 10 16 16 18 18 24

    3)

    i=3, j从2开始 包含了一号物品(4-8)和二号物品(6-10) 和三号物品(2-6)

    dp[2]=max(dp[2],dp[2-2]+6) = dp[2-2]+6 =6

    dp[3]=6

    dp[4]=max(dp[4],dp[4-2]+6) = dp[2]+6 =12  

    dp[4]错误!  因为从前到后会覆盖计算?

    (遍历的方向上需要从后往前遍历,从而保证子问题需要用到的数据不被覆盖https://www.cxyxiaowu.com/7895.html













    种一棵树最好的时间是十年前,其次是现在。
  • 相关阅读:
    SQLSERVER 中GO的作用
    工作相关工具介绍
    SQL Server 没有足够的内存继续执行程序 (mscorlib)的解决办法
    glyphicons-halflings-regular.woff2 not found 前台错误修正
    Asp.net MVC Pager分页实现
    金融相关网站
    Excel 函数使用
    C# 使用 Invoke 实现函数的白盒 UT 测试
    反编译工具
    SQL Server 数据库修改后不允许保存
  • 原文地址:https://www.cnblogs.com/islch/p/12568358.html
Copyright © 2011-2022 走看看