动态规划 (Dynamic Programming,DP) 是一种解决问题的方法,它将问题分解成多个子问题,通过求解这些子问题并将它们的解组合在一起,来求解原问题。这种方法可以解决许多类型的问题,包括最短路径、最大子序列和等。
下面我们来看一个简单的例子:求解最长公共子序列问题。这个问题涉及两个字符串,我们要找到它们的最长公共子序列。例如,如果我们有两个字符串”ABCBDAB”和”BDCABA”,那么它们的最长公共子序列就是”BCBA”。
为了求解这个问题,我们可以使用C++动态规划的方法。首先,我们要构建一个二维数组dp[][],其中dp[i][j]表示字符串1的前i个字符和字符串2的前j个字符的最长公共子序列的长度。我们从数组的左上角开始,根据字符串1和字符串2的每个字符来更新数组dp[][]。如果这两个字符相同,那么我们可以在它们的最长公共子序列的基础上再加上这个字符,所以dp[i][j]=dp[i-1][j-1]+1。否则,我们要从字符串1的前i-1个字符或字符串2的前j-1个字符中选择一个较长的最长公共子序列,所以dp[i][j]=max(dp[i-1][j],dp[i][j-1])。
代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1010;
int dp[N][N]; // dp[i][j]表示字符串1的前i个字符和字符串2的前j个字符的最长公共子序列的长度
string s1, s2; // 存储两个字符串
int main() {
cin >> s1 >> s2;
memset(dp, 0, sizeof dp); // 将dp数组初始化为0
// 填充dp数组
for (int i = 1; i <= s1.size(); i ++ )
for (int j = 1; j <= s2.size(); j ++ )
if (s1[i-1] == s2[j-1]) // 如果这两个字符相同
dp[i][j] = dp[i-1][j-1] + 1; // 在它们的最长公共子序列的基础上再加上这个字符
else // 否则
dp[i][j] = max(dp[i-1][j], dp[i][j-1]); // 从字符串1的前i-1个字符或字符串2的前j-1个字符中选择一个较长的最长公共子序列
cout << dp[s1.size()][s2.size()] << endl; // 输出最长公共子序列的长度
return 0;
}
上面的代码的时间复杂度为O(|s1|*|s2|),其中|s1|和|s2|分别表示字符串s1
和s2
的长度。