博客
关于我
简单易懂的背包问题
阅读量:631 次
发布时间:2019-03-13

本文共 2461 字,大约阅读时间需要 8 分钟。

动态规划是一种在计算机科学和数学中广泛应用的算法思想。它通过解决一系列子问题来解决更大的问题。通过让每一个子的结果只用一次,动态规划能够显著降低计算量,避免了重复计算,提高效率。

在国王的金矿问题中,动态规划的思路被清晰地体现出来。国王让大臣们解决更小的问题,并通过比较这些小问题的结果,最终汇总出最优解。每一个大臣的结果代表了一个子问题的解,而通过比较这些解,国王得出了最大的金子数量。

动态规划的关键点

  • 最优子结构:每一个子问题的结果都能够在更大的问题中发挥作用。
  • 子问题重叠:许多子问题具有相似的参数,可以通过记忆化存储这些结果,避免重复计算。
  • 边界:每一个问题都有一个基本的解决方式,例如,如果人数足够开采一个金矿,则只需考虑该金矿的价值。
  • 备忘录(记忆化):保存子问题的解,以便于后续问题的快速查询。
  • 时间分析:动态规划的时间复杂度通常远低于暴力法,特别是在处理较大的参数范围时,动态规划的效率更为突出。
  • 动态规划的应用

    在动态规划中,我们通常会构建一个二维数组来保存子问题的解。这个数组的维度通常由问题中的两个参数决定。例如,在金矿问题中,一个维度代表人数,另一个维度代表已经开采的金矿数量。

    通过递归地分解问题,我们能够逐步填充这个二维数组。每次处理一个问题时,先检查是否已经计算过(通过备忘录),如果已经计算过,就直接返回结果。如果没有计算过,则根据较小的子问题解来计算当前问题。

    代码实现

    以下是一个基于动态规划的代码片段,用于解决类似的背包问题:

    #include 
    #include
    #include
    using namespace std;void init(vector
    &peopleNeed, vector
    &gold, int n, int max_people) { ifstream inputFile("data.txt"); inputFile >> max_people >> n; for(int i = 0; i < n; ++i) { inputPipe >> peopleNeed[i] >> gold[i]; } inputFile.close(); vector
    > maxGold(max_people + 1, vector
    (n + 1, -1)); for(int i = 0; i <= max_people; ++i) for(int j = 0; j <= n; ++j) maxGold[i][j] = -1;}int getMaxGold(int people, int mineNum, const vector
    &peopleNeed, const vector
    &gold, const vector
    > &maxGold) { if(maxGold[people][mineNum] != -1) return maxGold[people][mineNum]; if(mineNum == 0) { if(people >= peopleNeed[0]) return gold[0]; else return 0; } if(people >= peopleNeed[mineNum]) { int option1 = (gold[mineNum] + getMaxGold(people - peopleNeed[mineNum], mineNum - 1, peopleNeed, gold, maxGold)); int option2 = getMaxGold(people, mineNum - 1, peopleNeed, gold, maxGold); return max(option1, option2); } else { return getMaxGold(people, mineNum - 1, peopleNeed, gold, maxGold); } maxGold[people][mineNum] = ret; return ret;}int main() { vector
    peopleNeed; vector
    gold; int max_people, n; init(peopleNeed, gold, n, max_people); cout << getMaxGold(10000, n - 1, peopleNeed, gold, maxGold) << endl; return 0;}

    样例输入输出

    输入:

    100 577 9222 2229 8750 4699 90

    输出:

    133

    总结

    动态规划通过拆分问题、记忆化结果和利用最优子结构,高效地解决了复杂的背包问题。在实际应用中,动态规划不仅提高了效率,还减少了计算的复杂度,使得在面对类似问题时,我们能够快速找到最优解。这也解释了为什么国王能够通过让大臣们分解问题,最终得出最大的金子数量。

    转载地址:http://kszoz.baihongyu.com/

    你可能感兴趣的文章
    Python块键盘/鼠标输入
    查看>>
    python在使用HTMLTestRunner时,报告为空,错误提示<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf_8'>...
    查看>>
    python在gpu上运行_【python】python开启GPU加速
    查看>>
    Python在def函数中使用for循环
    查看>>
    Python在def函数中使用for循环
    查看>>
    Python在Conda环境中,但在Windows虚拟环境中没有激活
    查看>>
    python系列【仅供参考】:python pip 错误 ModuleNotFoundError: No module named pip._internal 解决办法
    查看>>
    python图像条状状噪声,使用PYTHON PIL从验证码图像中删除背景嘈杂的线条
    查看>>
    Python图像处理:从内存加载jpeg
    查看>>
    python固定后缀(名物化词汇)词频统计:抽取+统计+可视化
    查看>>
    python商品评论数据采集与分析可视化系统 Flask框架 requests爬虫 NLP情感分析 毕业设计 源码
    查看>>
    python商品数据分析可视化系统(带爬虫)京东销售数据分析 计算机毕业设计 源码下载
    查看>>
    python商品库存管理系统 django框架 商品网站 MySQL数据库 源码下载 计算机毕业设计
    查看>>
    Python哪个版本最稳定好用2023.10.19
    查看>>
    Python和黑客技术的渊源
    查看>>
    Python和RF编写接口自动化
    查看>>
    python和js哪个难_【Python】记一次学习,Python 与 js 在实现闭包时的差异
    查看>>
    python和java哪个更值得学——来自知乎高赞回答
    查看>>
    python命名空间更改_Python模块xml.etree.ElementTree自动修改xml命名空间键
    查看>>
    Python命名中尾随下划线有什么好处?
    查看>>