博客
关于我
简单易懂的背包问题
阅读量: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互为主从实战设置详解及自动化备份(Centos7.2)
    查看>>
    mysql 主从关系切换
    查看>>
    MYSQL 主从同步文档的大坑
    查看>>
    mysql 主键重复则覆盖_数据库主键不能重复
    查看>>
    MySQL 事务的面试题总结
    查看>>
    Mysql 事务知识点与优化建议
    查看>>
    Mysql 优化 or
    查看>>
    mysql 优化器 key_mysql – 选择*和查询优化器
    查看>>
    MySQL 优化:Explain 执行计划详解
    查看>>
    Mysql 会导致锁表的语法
    查看>>
    mysql 使用sql文件恢复数据库
    查看>>
    mysql 修改默认字符集为utf8
    查看>>
    Mysql 共享锁
    查看>>
    MySQL 内核深度优化
    查看>>
    mysql 内连接、自然连接、外连接的区别
    查看>>
    mysql 写入慢优化
    查看>>
    mysql 分组统计SQL语句
    查看>>
    Mysql 分页
    查看>>
    Mysql 分页语句 Limit原理
    查看>>
    MySql 创建函数 Error Code : 1418
    查看>>