动态规划 (DP) 是一种用于解决最优化问题的算法技术,通过将问题分解成相互重叠的子问题并存储子问题的结果,从而避免重复计算。
以下是一个简单的动态规划模板,并通过一个经典问题来说明:斐波那契数列。
// 使用动态规划计算斐波那契数列
// 1. 定义状态数组
let dp = [];
// 2. 定义初始状态
dp[0] = 0;
dp[1] = 1;
// 3. 填充状态数组
function fib(n) {
// 已经计算过的子问题直接返回
if(dp[n] !== undefined) return dp[n];
// 根据状态转移方程进行计算
dp[n] = fib(n-1) + fib(n-2);
return dp[n];
}
console.log(fib(10)); // 输出 55
常见的动态规划题型包括:
- 序列型 DP:如斐波那契数列、最长递增子序列等。
- 划分型 DP:如将数组分成 m 段的问题、戳气球等。
- 背包型 DP:如 0-1 背包问题、完全背包问题等。
- 区间型 DP:如区间合并、矩阵链乘法等。
- 树型 DP:处理在树形结构中的最优化问题,如二叉树的最大路径和。
每种类型都有其特定的状态定义、初始化和状态转移方程。当面对一个问题时,首先确定问题类型,然后定义状态、初始状态和状态转移方程。经常练习这些题型有助于加深对动态规划的理解和应用。