1、最长公共序列(LCS)
#include <iostream> #include <algorithm> using namespace std; #define UP 1 #define LEFT 2 #define SLOPE 3 int dp[50][50]; int road[50][50]; char a[] = "ALGORITHM"; char b[] = "ALTRUISTIC"; void print(int x, int y) { if(x < 1 || y < 1) return; if(road[x][y] == SLOPE) { print(x-1, y-1); cout << a[x-1] << " "; } else if(road[x][y] == LEFT) print(x, y-1); else print(x-1, y); } int lcs() { int len1 = strlen(a), len2 = strlen(b); dp[0][0] = 0; for(int i = 1; i <= len1; ++i) dp[i][0] = 0; for(int i = 1; i <= len2; ++i) dp[0][i] = 0; for(int i = 1; i <= len1; ++i) { for(int j = 1; j <= len2; ++j) { if(a[i-1] == b[j-1]) { dp[i][j] = dp[i-1][j-1] + 1; road[i][j] = SLOPE; } else { dp[i][j] = max(dp[i-1][j], dp[i][j-1]); road[i][j] = dp[i-1][j] > dp[i][j-1] ? UP : LEFT; } } } return dp[len1][len2]; } int main(void) { memset(dp, 0, sizeof(dp)); memset(road, 0, sizeof(road)); cout << lcs() << endl; print(strlen(a), strlen(b)); return 0; }
2、最大子序列和
#include <iostream> using namespace std; int a[] = { //-2, 11, -4, 13, -5, -2 -6, 2, 4, -7, 5, 3, 2, -1, 6, -9, 10, -2 }; int dp[30], x = -1; int lss() { dp[0] = a[0]; int len = sizeof(a) / sizeof(*a), ret = -255; for(int i = 1; i < len; ++i) { dp[i] = dp[i-1] > 0 ? dp[i-1]+a[i] : a[i]; if(ret < dp[i]) { ret = dp[i]; x = i; } } return ret; } void suffix() { int i; for(i = x; i >= 0; --i) { if(dp[i] < 0) break; } cout << "具有最大和子序列的下标位置为:" << i+1 << " " << x << endl; } int main(void) { memset(dp, 0, sizeof(dp)); cout << lss() << endl; suffix(); return 0; }
3、最长递增子序列长度(LIS)
#include <iostream> using namespace std; int a[] = { 1, -1, 2, -3, 4, -5, 6, -7 }; int dp[25]; int lis() { int len = sizeof(a) / sizeof(*a), ret = -1; for(int i = 0; i < len; ++i) { dp[i] = 1; for(int j = 0; j < i; ++j) { if(a[i] > a[j] && dp[j] + 1 > dp[i]) dp[i] = dp[j] + 1; } if(ret < dp[i]) ret = dp[i]; } return ret; } int main(void) { memset(dp, 0, sizeof(dp)); cout << lis() << endl; return 0; }
4、最长连续公共子序列长度(最长公共子串)
#include <iostream> using namespace std; int opt[65535]; int max(int a, int b) { return a > b ? a : b; } int maxSubLen(const char *src, const char *trg) { int len1 = strlen(src); int len2 = strlen(trg); int largest = -1; for(int j = 0; j < len2; ++j) { for(int i = len1 - 1; i >= 0; --i) { if(src[i] == trg[j]) { if(i == 0) opt[i] = 1; else opt[i] = opt[i-1] + 1; if(largest < opt[i]) largest = opt[i]; } else opt[i] = 0; } } return largest; } int main(void) { char text[] = "acbac"; char query[] = "acaccbabb"; memset(opt, 0, sizeof(opt)); cout << maxSubLen(query, text) << endl; return 0; }
5、矩阵最大子矩阵和
#include <iostream> using namespace std; const int m = 3, n = 3; int a[10][10] = { {7, -8, 9}, {-4, 5, 6}, {1, 2, -3} }; int b[10]; int dp[10]; int start, end; int lss() { dp[0] = b[0]; int res = dp[0]; start = 0, end = 0; for(int i = 1; i < n; ++i) { // dp[i] = dp[i-1] > 0 ? dp[i-1] + b[i] : b[i]; if(dp[i-1] < 0) { start = i; dp[i] = b[i]; } else dp[i] = dp[i-1] + b[i]; // res = dp[i] > res ? dp[i] : res; if(dp[i] > res) { res = dp[i]; end = i; } } return res; } int main(void) { int x1 = 0, x2 = 0, y1 = 0, y2 = 0; int maxv = a[x1][y1]; for(int l1 = 0; l1 < m; ++l1) { for(int l2 = l1+1; l2 < m; ++l2) { memset(b, 0, sizeof(b)); int i; for(i = l1; i < l2; ++i) { for(int j = 0; j < n; ++j) { b[j] += a[i][j]; } } int t = lss(); if(maxv < t) { maxv = t; x1 = l1; x2 = l2; y1 = start; y2 = end; } } } cout << "第" << x1+1 << "行到" << x2 + 1 << "行,第" << y1+1 << "列到第" << y2+1 << "列构成的子矩阵和最大,为:" << maxv << endl; return 0; }