元素星在线活动查询中心

元素星在线活动查询中心

shape
  • Home
  • 活动查询
  • 动态规划

动态规划

  • 2025-11-28 14:56:16
  • admin

什么是动态规划

动态规划(Dynamic Programming,简称 DP)是一种解决复杂问题的算法思想,通过将问题分解为更小的子问题,并将子问题的解存储起来以避免重复计算,从而提高算法的效率。动态规划通常用于优化问题,即在给定的约束条件下,找到最优解。

动态规划的核心

动态规划中状态是核心,通常用一个或多个变量表示,即dp[i]或dp[i][j],然后用状态转移方程进行推导,但要注意初始状态和边界条件。

使用场景

动态规划适用于具有以下特征的问题:

最优子结构:

问题的最优解包含其子问题的最优解,即,可以通过子问题的最优解构造出原问题的最优解。

重叠子问题:

问题的递归求解过程中,存在大量的重复计算。动态规划通过存储子问题的解来避免重复计算。

常见应用

背包问题

0-1背包

dp[i][j] 表示前 i 种物品在容量为 j 的背包中能达到的最大价值

dp[0][j] = 0:不选任何物品时,价值为0。

dp[i][0] = 0:背包容量为0时,价值为0。

状态转移方程:

dp[i][j]=max(dp[i−1][j],dp[i−1][j−w[i]]+v[i])

1234567891011121314int knapsack_01(vector& w, vector& v, int W) { vector> dp(w.size()+1, vector(W+1, 0)); for (int i = 1; i <= w.size(); ++i) { for (int j = 1; j <= W; ++j) { if (j >= w[i-1]) { dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i-1]] + v[i-1]); } else { dp[i][j] = dp[i-1][j]; } } } return dp[w.size()][W];}

完全背包

1234567891011121314int knapsack_complete(vector& w, vector& v, int W) { vector> dp(w.size()+1, vector(W+1, 0)); for (int i = 1; i <= w.size(); ++i) { for (int j = 1; j <= W; ++j) { if (j >= w[i-1]) { dp[i][j] = max(dp[i-1][j], dp[i][j-w[i-1]] + v[i-1]); } else { dp[i][j] = dp[i-1][j]; } } } return dp[w.size()][W];}

可以优化

1234567891011int knapsack_complete(vector& w, vector& v, int W) { vector dp(W + 1, 0); for (int i = 0; i < w.size(); ++i) { for (int j = w[i]; j <= W; ++j) { dp[j] = max(dp[j], dp[j - w[i]] + v[i]); } } return dp[W];}

序列问题

最长递增子序列(LIS)

dp[i] 表示以第 i 个元素结尾的最长递增子序列的长度

dp[i] = 1:每个元素自身可以看作一个长度为1的递增子序列。

状态转移方程:

dp[i]=max(dp[i],dp[j]+1)

123456789int n = arr.size();vector dp(n, 1);for (int i = 1; i < n; ++i) { for (int j = 0; j < i; ++j) { if (arr[j] < arr[i]) { dp[i] = max(dp[i], dp[j] + 1); } }}

最长公共子序列(LCS)

dp[i][j] 表示字符串 X 的前 i 个字符和字符串 Y 的前 j 个字符的最长公共子序列的长度。

dp[0][j] = 0:空字符串与任何字符串的最长公共子序列长度为0。

dp[i][0] = 0:空字符串与任何字符串的最长公共子序列长度为0。

状态转移方程:

如果 X[i−1]==Y[j−1]:

dp[i][j]=dp[i−1][j−1]+1

如果 X[i−1]!=Y[j−1]:

dp[i][j]=max(dp[i−1][j],dp[i][j−1])

12345678910111213int m = X.size();int n = Y.size();vector> dp(m + 1, vector(n + 1, 0));for (int i = 1; i <= m; ++i) { for (int j = 1; j <= n; ++j) { 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]); } }}

Previous Post
火爆全网的“city不city”到底是什么意思?
Copyright © 2088 元素星在线活动查询中心 All Rights Reserved.
友情链接