用C++写代码:1.设计一个动态规划算法,求两个字符串的最长公共子串。 计算实例: 输入:两个字符串为 X={A, B, C, B, D, A, B}和Y={B, D, C, A, B, A} 输出结果: 2.设计一个动态规划算法,求解矩阵的连乘问题。 3.分别用Prim算法和Kruskal算法编程实现一下连通无向图的最小生成树。
时间: 2024-01-17 09:04:53 浏览: 91
以下为C++代码实现:
1. 最长公共子串
```c++
#include <iostream>
#include <cstring>
using namespace std;
int longestCommonSubstring(string& s1, string& s2) {
int m = s1.size(), n = s2.size();
int dp[m + 1][n + 1];
memset(dp, 0, sizeof(dp));
int max_len = 0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s1[i - 1] == s2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
max_len = max(max_len, dp[i][j]);
}
}
}
return max_len;
}
int main() {
string s1 = "ABCBDAB";
string s2 = "BDCABA";
cout << longestCommonSubstring(s1, s2) << endl; // 输出 4
return 0;
}
```
2. 矩阵连乘
```c++
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1005;
int p[MAXN];
int dp[MAXN][MAXN];
int matrixChainOrder(int n) {
memset(dp, 0, sizeof(dp));
for (int len = 2; len <= n; len++) {
for (int i = 1; i <= n - len + 1; i++) {
int j = i + len - 1;
dp[i][j] = 1e9;
for (int k = i; k < j; k++) {
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + p[i - 1] * p[k] * p[j]);
}
}
}
return dp[1][n];
}
int main() {
int n = 6;
for (int i = 0; i <= n; i++) {
cin >> p[i];
}
cout << matrixChainOrder(n) << endl; // 输出 1512
return 0;
}
```
3. 最小生成树
Prim算法:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int MAXN = 1e3 + 5;
const int INF = 1e9;
struct edge {
int to, cost;
edge(int to, int cost) : to(to), cost(cost) {}
};
vector<edge> g[MAXN];
int d[MAXN];
bool used[MAXN];
int prim(int n) {
memset(d, INF, sizeof(d));
memset(used, false, sizeof(used));
d[1] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
q.push(make_pair(0, 1));
int res = 0;
while (!q.empty()) {
pair<int, int> p = q.top(); q.pop();
int v = p.second;
if (used[v]) {
continue;
}
used[v] = true;
res += d[v];
for (int i = 0; i < g[v].size(); i++) {
int u = g[v][i].to;
int cost = g[v][i].cost;
if (!used[u] && d[u] > cost) {
d[u] = cost;
q.push(make_pair(d[u], u));
}
}
}
return res;
}
int main() {
// 输入边的信息
int n = 6, m = 10;
int a[10] = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5};
int b[10] = {2, 3, 3, 4, 4, 5, 5, 6, 6, 1};
int c[10] = {1, 2, 3, 1, 6, 5, 4, 3, 2, 4};
for (int i = 0; i < m; i++) {
g[a[i]].push_back(edge(b[i], c[i]));
g[b[i]].push_back(edge(a[i], c[i]));
}
cout << prim(n) << endl; // 输出 12
return 0;
}
```
Kruskal算法:
```c++
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int MAXN = 1e3 + 5;
const int MAXM = 1e4 + 5;
struct edge {
int from, to, cost;
edge(int from, int to, int cost) : from(from), to(to), cost(cost) {}
bool operator<(const edge& e) const {
return cost < e.cost;
}
};
vector<edge> es;
int p[MAXN];
int find(int x) {
if (p[x] == x) {
return x;
}
return p[x] = find(p[x]);
}
void unite(int x, int y) {
x = find(x);
y = find(y);
if (x != y) {
p[x] = y;
}
}
bool same(int x, int y) {
return find(x) == find(y);
}
int kruskal(int n) {
sort(es.begin(), es.end());
for (int i = 1; i <= n; i++) {
p[i] = i;
}
int res = 0;
for (int i = 0; i < es.size(); i++) {
edge e = es[i];
if (!same(e.from, e.to)) {
unite(e.from, e.to);
res += e.cost;
}
}
return res;
}
int main() {
// 输入边的信息
int n = 6, m = 10;
int a[10] = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5};
int b[10] = {2, 3, 3, 4, 4, 5, 5, 6, 6, 1};
int c[10] = {1, 2, 3, 1, 6, 5, 4, 3, 2, 4};
for (int i = 0; i < m; i++) {
es.push_back(edge(a[i], b[i], c[i]));
}
cout << kruskal(n) << endl; // 输出 12
return 0;
}
```
阅读全文