动态规划01
发布时间 : 2022-03-31 13:22
字数:589
阅读 :
动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
由于动态规划并不是某种具体的算法,而是一种解决特定问题的方法,因此它会出现在各式各样的数据结构中,与之相关的题目种类也更为繁杂。
题目: 给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。
思路:
代码:
$O(n^2)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> #include <algorithm> using namespace std;const int N = 1010 ;int n;int a[N], f[N];int main () { scanf ("%d" , &n); for (int i = 1 ; i <= n; i ++ ) scanf ("%d" , &a[i]); for (int i = 1 ; i <= n; i ++ ) { f[i] = 1 ; for (int j = 1 ; j < i; j ++ ) if (a[j] < a[i]) f[i] = max (f[i], f[j] + 1 ); } int res = 0 ; for (int i = 1 ; i <= n; i ++ ) res = max (res, f[i]); printf ("%d\n" , res); return 0 ; }
q[i]:所有长度为i的上升子序列中结尾最小的数
$O(nlogn)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> #include <algorithm> using namespace std;const int N = 100010 ;int n;int a[N];int q[N];int main () { scanf ("%d" , &n); for (int i = 0 ; i < n; i ++ ) scanf ("%d" , &a[i]); int len = 0 ; for (int i = 0 ; i < n; i ++ ) { int l = 0 , r = len; while (l < r) { int mid = l + r + 1 >> 1 ; if (q[mid] < a[i]) l = mid; else r = mid - 1 ; } len = max (len, r + 1 ); q[r + 1 ] = a[i]; } printf ("%d\n" , len); return 0 ; }
题目: 思路: 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <algorithm> using namespace std;const int N = 1010 ;int n, m;char a[N], b[N];int f[N][N];int main () { scanf ("%d%d" , &n, &m); scanf ("%s%s" , a + 1 , b + 1 ); for (int i = 1 ; i <= n; i ++ ) for (int j = 1 ; j <= m; j ++ ) { f[i][j] = max (f[i - 1 ][j], f[i][j - 1 ]); if (a[i] == b[j]) f[i][j] = max (f[i][j], f[i - 1 ][j - 1 ] + 1 ); } printf ("%d\n" , f[n][m]); return 0 ; }
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1149440709@qq.com