什么是动态规划(DP)?(C++版)

动态规划基本概念

动态规划是一种解决复杂问题的优化技术,通过将问题分解为子问题并存储子问题的解来避免重复计算。适用于具有重叠子问题和最优子结构性质的问题。

动态规划实现步骤

问题分析 明确问题的状态定义,确定状态转移方程,识别边界条件。例如在斐波那契数列中,状态定义为dp[i]表示第i项的值,状态转移方程为dp[i] = dp[i-1] + dp[i-2]

初始化DP表 根据问题需求创建一维或二维数组存储中间结果。初始化边界条件,如斐波那契数列中dp[0] = 0dp[1] = 1

填充DP表 按顺序或逆序填充DP表,确保在计算当前状态时所需的前驱状态已被计算。例如斐波那契数列从i=2开始迭代至目标值。

提取结果 DP表的最后一个元素或特定位置通常为最终解。例如斐波那契数列返回dp[n]

经典问题示例

斐波那契数列

cpp 复制代码
int fib(int n) {
    if (n <= 1) return n;
    int dp[n+1];
    dp[0] = 0; dp[1] = 1;
    for (int i = 2; i <= n; ++i) {
        dp[i] = dp[i-1] + dp[i-2];
    }
    return dp[n];
}

最长公共子序列(LCS)

cpp 复制代码
int lcs(string X, string Y) {
    int m = X.length(), n = Y.length();
    int dp[m+1][n+1];
    for (int i = 0; i <= m; ++i) {
        for (int j = 0; j <= n; ++j) {
            if (i == 0 || j == 0) dp[i][j] = 0;
            else if (X[i-1] == Y[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
            else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
        }
    }
    return dp[m][n];
}

优化技巧

空间优化 对于某些问题,可通过滚动数组或压缩状态减少空间复杂度。例如斐波那契数列只需保存前两个状态:

cpp 复制代码
int fib(int n) {
    if (n <= 1) return n;
    int prev = 0, curr = 1;
    for (int i = 2; i <= n; ++i) {
        int next = prev + curr;
        prev = curr;
        curr = next;
    }
    return curr;
}

备忘录法 自顶向下递归配合缓存已计算结果,避免重复计算:

cpp 复制代码
unordered_map<int, int> memo;
int fib(int n) {
    if (n <= 1) return n;
    if (memo.find(n) != memo.end()) return memo[n];
    return memo[n] = fib(n-1) + fib(n-2);
}

常见应用场景

  • 背包问题(01背包、完全背包)
  • 矩阵链乘法
  • 最短路径问题(Floyd-Warshall算法)
  • 字符串编辑距离
  • 股票买卖问题

通过系统性地分解问题、存储中间结果和构建状态转移方程,动态规划能高效解决许多优化问题。

相关推荐
2301_8184190120 小时前
C++中的解释器模式变体
开发语言·c++·算法
爱学习的大牛12320 小时前
windows tcpview 类似功能 c++
c++
biter down21 小时前
C++11 统一列表初始化+std::initializer_list
开发语言·c++
ShineWinsu1 天前
爬虫对抗:ZLibrary反爬机制实战分析技术文章大纲
c++
charlie1145141911 天前
通用GUI编程技术——Win32 原生编程实战(十六)——Visual Studio 资源编辑器使用指南
开发语言·c++·ide·学习·gui·visual studio·win32
DpHard1 天前
现代 C++ 中 push 接口为何提供 const T& 与 T&& 两个重载
c++
U-52184F691 天前
深度解析:从 Qt 的 Q_D 宏说起,C++ 工业级 SDK 是如何保证 ABI 稳定性的
数据库·c++·qt
hz_zhangrl1 天前
CCF-GESP 等级考试 2026年3月认证C++三级真题解析
c++·算法·程序设计·gesp·gesp2026年3月·gesp c++三级
kyle~1 天前
C++----函数指针与函数指针类型 返回值类型 (*类型名)(参数列表)
开发语言·c++
努力中的编程者1 天前
二叉树(C语言底层实现)
c语言·开发语言·数据结构·c++·算法