• 软件部2022届讲课底稿------多重背包问题


    本文为软件部2022届讲课底稿,作者5月份的时候决定出国,遂卷绩点和英语去了,本文诸多疏漏请多包涵,毕竟不是专业算法选手。

    目录

    背包问题的背景是什么?

    多重背包的问题的背景

    完全背包问题的分析

    朴素做法 

    多重背包的二进制优化 

    二进制优化代码 


    背包问题的背景是什么?

    现在有一个背包,体积是v,给定一些物品,这些物品有他们各自的体积vi,也有他们各自的价值权重wi,想要找出怎么装背包,才可以使背包里物品的总价值最大。

    问题一:背包必须装满吗?

    答:不是。

    多重背包的问题的背景

    现在手上有一个背包,给定 n 件物品,每件物品的数量有一定的限制。物品 i 的重量是 wi,其价值为 vi,背包的容量为 C。问应如 何装入背包中的物品,使得装入背包中物品的总价值最大?

    问题二:多重背包和其他背包的区别?

    答:多重背包中没见物品的数量有一定的限制,完全背包问题每件物品可以选取无限次,01背包问题中每件物品只可以选取一次。

    完全背包问题的分析

    问题三:多重背包问题中的公式该如何推导? 

    朴素做法 

    1. #include
    2. using namespace std;
    3. int dp[105][105];
    4. int v[105],w[105],s[105];
    5. int main()
    6. {
    7. int n,m;cin>>n>>m;
    8. for(int i=1;i<=n;i++)
    9. {
    10. cin>>v[i]>>w[i]>>s[i];
    11. }
    12. for(int i=1;i<=n;i++)
    13. {
    14. for(int j=0;j<=m;j++)
    15. {
    16. for(int k=0;k<=s[i]&&v[i]*k<=j;k++)//表示每种物品的件数
    17. {
    18. dp[i][j]=max(dp[i][j],dp[i-1][j-k*v[i]]+k*w[i]);
    19. }
    20. }
    21. }
    22. cout<
    23. return 0;
    24. }

    多重背包的二进制优化 

    问题四:多重背包的朴素做法的时间复杂度?

    答:O(n*m*k),n表示的是物品的种类,m表示的是体积,k表示的是每种物品选取的数量上限。

    问题五:多重背包的二进制优化是什么原理呢?时间复杂度又是多少呢?

    答:

    时间复杂度:O(n*m*log k)

    原理:

    简而言之,二进制拆分,就是已知每种物件下面对应的s个物品上限,将s个物品打包拆分为log s个新的物品。这样下来已知有n种物品,每种物品的上限是s,总共就等价于打包了n*log s件物品,如下图所示。

    二进制优化代码 

    1. #include
    2. using namespace std;
    3. const int N=12010;const int M=2010;
    4. int v[N],w[N],dp[M];
    5. int n,m;
    6. int main()
    7. {
    8. cin>>n>>m;
    9. int cnt=1;//表示打包的第一件物品
    10. for(int i=1;i<=n;i++)
    11. {
    12. int a,b,s;//a表示的是体积,b表示的是价值,s表示的是第i种物品的数量
    13. cin>>a>>b>>s;
    14. int k=1;//二进制数对应的倍数
    15. while(k<=s)
    16. {
    17. v[cnt]=k*a;
    18. w[cnt]=k*b;
    19. k*=2;
    20. cnt++;
    21. }
    22. if(s>0)
    23. {
    24. v[cnt]=s*a;
    25. w[cnt]=s*b;
    26. cnt++;
    27. }
    28. }
    29. for(int i=1;i<=cnt;i++)
    30. {
    31. for(int j=m;j>=v[i];j--)
    32. {
    33. dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
    34. }
    35. }
    36. cout<
    37. return 0;
    38. }
  • 相关阅读:
    面试突击83:什么情况会导致@Transactional事务失效?
    Zemax操作36--一个选择初始结构的例子
    Netty核心API介绍
    jQuery入门
    Swagger ui接口自动化批量漏洞测试
    httprunner环境变量
    身份证测试图片
    【VUE+ elementUI 实现动态表头渲染】
    shell脚本通过解析日志使用串口开关屏知识点整理
    Python 生命游戏(tkinter版)
  • 原文地址:https://blog.csdn.net/QDQE232/article/details/126314352