线性$DP$:数字三角形
//线性 DP:数字三角形 int Triangle(int n, int a[][100]){ int DP[n + 1][n + 1]; memset(DP, -0x3f, sizeof(DP)); DP[1][1] = a[1][1]; for(int i = 2; i <= n; i++){ for(int j = 1; j <= i; j++){ DP[i][j] = max(DP[i - 1][j - 1] + a[i][j], DP[i - 1][j] + a[i][j]); } } int res = 0xc0c0c0c0; for(int i = 1; i <= n; i++){ res = max(res, DP[n][i]); } return res; }
线性$DP$:最长上升子序列
//线性 DP:最长上升子序列 int LongestIncreasingSubsequence(int n, int a[]){ int DP[n + 1]; memset(DP, 0, sizeof(DP)); for(int i = 1; i <= n; i++){ DP[i] = 1; for(int j = 1; j < i; j++){ if (a[j] < a[i]){ DP[i] = max(DP[i], DP[j] + 1); }; } } int res = 0; for(int i = 1; i <= n; i++){ res = max(res, DP[i]); } return res; } //线性 DP:最长不下降子序列(二分优化) int LongestIncreasingSubsequence(int n, int a[]){ int DP[n + 1], l[n + 1]; memset(DP, 0, sizeof(DP)); memset(l, 0, sizeof(l)); int ans = 1; DP[1] = 1; l[1] = a[1]; for(int i = 2; i <= n; i++){ DP[i] = 1; if(a[i] <= l[ans1]){ dp[i] = ++ans; }else{ int j = upper_bound(l + 1, l + ans1 + 1, a[i], greater<int>()) - l; dp[i] = j; } l[dp[i]] = a[i]; } return ans; }
线性$DP$:最长公共子序列
//线性 DP:最长公共子序列 int LongestCommonSubsequence(int n, int m, char a[], char b[]){ int DP[n + 1][m + 1]; memset(DP, 0, sizeof(DP)); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ DP[i][j] = max(DP[i - 1][j], DP[i][j - 1]); if(a[i] == b[j]){ DP[i][j] = max(DP[i][j], DP[i - 1][j - 1] + 1); } } } return DP[n][m]; }
区间$DP$:石子合并
//区间 DP:石子合并 int StoneMerging(int n, int s[]){ int DP[n + 1][n + 1]; for(int i = 1; i <= n; i++){ s[i] += s[i - 1]; } memset(DP, 0, sizeof(DP)); for(int len = 2; len <= n; len++){ for(int i = 1; i + len - 1 <= n; i++){ int l = i, r = i + len - 1; DP[l][r] = 0x3f3f3f3f; for(int k = l, k < r; k++){ DP[l][r] = min(DP[l][r], DP[l][k] + DP[k + 1][r] + s[r] - s[l - 1]); } } } return DP[1][n]; }