c++动态规划

动态规划的基本概念

动态规划通常用于优化解决以下类型的问题:

为了避免重复计算,动态规划会使用一个数组或表格存储已经计算过的子问题的解,从而实现“记忆化”效果,降低时间复杂度。

动态规划的实现步骤

动态规划的解题一般遵循以下步骤:

  1. 定义状态:设定一个状态表示。例如,对于一个求最短路径的问题,可以定义dp[i]表示到节点i的最短路径长度。

  2. 状态转移方程:找出当前状态与之前状态之间的关系。这是动态规划的核心。比如,假设dp[i]的值可以通过dp[i-1]和dp[i-2]计算得出,那么状态转移方程可以表示为:dp[i] = min(dp[i-1], dp[i-2]) + cost[i]。

  3. 初始化:根据题意初始化dp数组的值。例如,若dp[0]表示开始状态,它的值可以设为0或其他值。

  4. 计算并获取结果:依据状态转移方程逐步填充dp数组,最终的解通常会在dp[n]或dp[n-1]等位置得到。

经典例题讲解

  1. 斐波那契数列

求解第n项的斐波那契数。斐波那契数列的状态转移方程是:

[ dp[i] = dp[i-1] + dp[i-2] ]

其中dp[0] = 0,dp[1] = 1。

int fibonacci(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];
}

Reference

背包算法