博客
关于我
简单易懂的背包问题
阅读量:630 次
发布时间: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/

    你可能感兴趣的文章
    mysql 存储过程每隔一段时间执行一次
    查看>>
    mysql 存在update不存在insert
    查看>>
    Mysql 学习总结(86)—— Mysql 的 JSON 数据类型正确使用姿势
    查看>>
    Mysql 学习总结(87)—— Mysql 执行计划(Explain)再总结
    查看>>
    Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键
    查看>>
    Mysql 学习总结(89)—— Mysql 库表容量统计
    查看>>
    mysql 实现主从复制/主从同步
    查看>>
    mysql 审核_审核MySQL数据库上的登录
    查看>>
    mysql 导入 sql 文件时 ERROR 1046 (3D000) no database selected 错误的解决
    查看>>
    mysql 导入导出大文件
    查看>>
    MySQL 导出数据
    查看>>
    mysql 将null转代为0
    查看>>
    mysql 常用
    查看>>
    MySQL 常用列类型
    查看>>
    mysql 常用命令
    查看>>
    Mysql 常见ALTER TABLE操作
    查看>>
    MySQL 常见的 9 种优化方法
    查看>>
    MySQL 常见的开放性问题
    查看>>
    Mysql 常见错误
    查看>>
    mysql 常见问题
    查看>>