博客
关于我
C++动态规划算法学习&练习
阅读量:330 次
发布时间:2019-03-03

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

C++动态规划学习与实践

动态规划题目特点

动态规划是一种解决复杂问题的强大工具,常用于计算机科学和工程领域。以下是动态规划题目的典型特点:

  • 计数问题

    • 如路径计数问题,计算从左上角走到右下角的不同路径数量。
    • 如硬币问题,计算达到某个金额所需的最小硬币数量。
  • 求最大最小值

    • 如路径最大和问题,找到从左上角到右下角路径中数字之和的最大值。
    • 如最长上升子序列问题,找到数组中最长的递增子序列的长度。
  • 求存在性

    • 如跳游戏问题,判断是否可以从起始点跳到终点。
    • 如子数组和问题,判断是否存在一个子数组的和等于目标值。
  • 动态规划步骤

    动态规划的核心步骤包括:

  • 确定状态

    • 最后一步:确定最优策略中使用的最后一步(如硬币问题中的最后一枚硬币)。
    • 化成子问题:将当前问题转化为更小的子问题。
  • 转移方程

    • 硬币问题:f[X] = min{f[X-2]+1, f[X-5]+1, f[X-7]+1}。
    • 路径计数问题:f[i][j] = f[i-1][j] + f[i][j-1]。
  • 初始条件和边界情况

    • 初始化:f[0] = 0(如硬币问题)。
    • 边界条件:f[i][0] = 1(路径计数问题)。
    • 无解标记:f[Y] = 无穷大(如硬币问题)。
  • 计算顺序

    • 硬币问题:从小到大依次计算。
    • 路径计数问题:按行或列顺序计算。
  • 动态规划代码示例

    1. Coin Change(硬币问题)

    问题:给定不同面值的硬币和一个总金额,求最少需要多少枚硬币才能凑出该金额。

    示例代码

    #include 
    #include
    #include
    #include
    using namespace std;int coinChange(vector
    coins, int amount) { vector
    dp(amount + 1, INT_MAX); dp[0] = 0; for (int i = 1; i <= amount; ++i) { for (int j = 0; j < coins.size(); ++j) { if (i >= coins[j] && dp[i - coins[j]] != INT_MAX) { dp[i] = min(dp[i], dp[i - coins[j]] + 1); } } } return dp[amount] != INT_MAX ? dp[amount] : -1;}int main() { vector
    coins; int temp; while (cin >> temp && getchar() != '\n') { coins.push_back(temp); } coins.push_back(temp); int amount; cin >> amount; cout << coinChange(coins, amount); return 0;}

    分析:代码中使用动态规划数组dp来记录最少硬币数量。从左到右依次计算每个金额,确保计算顺序正确。

    2. Unique Paths(路径计数问题)

    问题:计算从左上角走到右下角的不同路径数量。

    示例代码

    #include 
    #include
    using namespace std;int uniquePaths(int m, int n) { vector
    > dp(m, vector
    (n, 0)); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (i == 0 && j == 0) { dp[i][j] = 1; } else if (i == 0 || j == 0) { dp[i][j] = 1; } else { dp[i][j] = dp[i-1][j] + dp[i][j-1]; } } } return dp[m-1][n-1];}int main() { int m, n; cin >> m >> n; cout << uniquePaths(m, n); return 0;}

    分析:代码中使用二维数组dp记录路径数量。从左上角开始,逐步计算每个格子的路径数量。

    3. Jump Game(跳游戏问题)

    问题:判断青蛙是否能从起始点跳到终点。

    示例代码

    #include 
    #include
    #include
    #include
    using namespace std;bool canJump(vector
    a) { int n = a.size(); vector
    dp(n, false); dp[0] = true; for (int j = 1; j < n; ++j) { for (int i = 0; i < j; ++i) { if (dp[i] && i + a[i] >= j) { dp[j] = true; break; } } } return dp[n-1];}int main() { vector
    a; int temp; while (cin >> temp && getchar() != '\n') { a.push_back(temp); } a.push_back(temp); cout << canJump(a) ? "True" : "False"; return 0;}

    分析:代码中使用动态规划数组dp记录能否到达每个石头位置。从左到右依次判断是否能跳到下一个石头。

    4. Maximum Product Subarray(最大子数组乘积)

    问题:找到数组中最大的连续子数组的乘积。

    示例代码

    #include 
    #include
    #include
    #include
    using namespace std;int MaxProductSubarray(const vector
    & a) { if (a.empty()) return 0; vector
    dp(a.size(), 0); dp[0] = a[0]; int maxn = dp[0]; for (int i = 1; i < a.size(); ++i) { dp[i] = max(dp[i-1] * a[i], a[i]); maxn = max(maxn, dp[i]); } return maxn;}int main() { vector
    a; int temp; while (cin >> temp && getchar() != '\n') { a.push_back(temp); } a.push_back(temp); cout << MaxProductSubarray(a); return 0;}

    分析:代码中使用动态规划数组dp记录当前子数组的最大乘积。从左到右依次计算每个元素的最大乘积。

    总结

    动态规划是一种强大的算法设计方法,通过将复杂问题分解为更小的子问题并通过状态转移求解,最终得到最优解。以上代码示例展示了动态规划在不同问题中的应用场景,理解这些代码可以帮助更好地掌握动态规划的原理和实现方法。

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

    你可能感兴趣的文章
    NIO笔记---上
    查看>>
    NIO蔚来 面试——IP地址你了解多少?
    查看>>
    NISP一级,NISP二级报考说明,零基础入门到精通,收藏这篇就够了
    查看>>
    NISP国家信息安全水平考试,收藏这一篇就够了
    查看>>
    NIS服务器的配置过程
    查看>>
    Nitrux 3.8 发布!性能全面提升,带来非凡体验
    查看>>
    NiuShop开源商城系统 SQL注入漏洞复现
    查看>>
    NI笔试——大数加法
    查看>>
    NLog 自定义字段 写入 oracle
    查看>>
    NLog类库使用探索——详解配置
    查看>>
    NLP 基于kashgari和BERT实现中文命名实体识别(NER)
    查看>>
    NLP 模型中的偏差和公平性检测
    查看>>
    Vue3.0 性能提升主要是通过哪几方面体现的?
    查看>>
    NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器
    查看>>
    NLP_什么是统计语言模型_条件概率的链式法则_n元统计语言模型_马尔科夫链_数据稀疏(出现了词库中没有的词)_统计语言模型的平滑策略---人工智能工作笔记0035
    查看>>
    NLP三大特征抽取器:CNN、RNN与Transformer全面解析
    查看>>
    NLP学习笔记:使用 Python 进行NLTK
    查看>>
    NLP度量指标BELU真的完美么?
    查看>>
    NLP的不同研究领域和最新发展的概述
    查看>>
    NLP的神经网络训练的新模式
    查看>>