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;
}