算是一道模版题 练习动态规划
题目
#include <iostream>
using namespace std;
const int MAX_N = 1000; // 假设最大长度为 1000
int a[MAX_N], b[MAX_N];
int f[MAX_N + 1][MAX_N + 1]; // 注意数组大小为 n+1 和 m+1
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= m; i++)
cin >> b[i];
for (int i = 0; i <= n; i++)
f[i][0] = 0; // 初始化边界条件
for (int j = 0; j <= m; j++)
f[0][j] = 0; // 初始化边界条件
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (a[i] == b[j])
f[i][j] = f[i - 1][j - 1] + 1;
else
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
}
}
cout << f[n][m];
return 0;
}
f[i][j]存的是a数组的前i个数和b数组的前j个数的最长公共子序列
让计算机从头到尾遍历一遍直接输出,时间复杂度是O(m*n)
动态规划的时间复杂度通常取决于状态的个数以及状态之间的转移关系。假设问题规模为 n,状态数为 m,那么动态规划的时间复杂度可以表示为 O(n * m)。
具体来说,常见的动态规划算法有两种情况:
1. **自底向上的递推:** 在这种情况下,通常使用一个二维数组来表示状态转移表,循环嵌套用于填充表格。对于每个状态,需要考虑其依赖的其他状态,因此时间复杂度为 O(n * m)。
2. **自顶向下的递归 + 记忆化搜索:** 在这种情况下,使用递归函数进行状态转移,并通过记忆化搜索(Memoization)来避免重复计算。时间复杂度同样为 O(n * m),但由于记忆化搜索可以减少冗余计算,实际运行时间可能较短。
需要注意的是,动态规划问题的时间复杂度与问题本身的性质有关,不同问题可能具有不同的时间复杂度。