C++--动态规划路径问题
发布人:shili8
发布时间:2025-03-12 09:33
阅读次数:0
**C++ 中的动态规划路径问题**
在计算机科学中,动态规划是一种常见的算法技巧,用于解决复杂的问题。它通过分解问题为更小的子问题,并以递归方式求解这些子问题来实现。这种方法可以显著减少计算量和时间。
本文将讨论 C++ 中的一些动态规划路径问题及其解决方案。
###1. 最长上升子序列(Longest Increasing Subsequence,LIS)
最长上升子序列是指从一组数字中选择出一个子序列,使得该子序列中的每个数字都大于前面的数字。例如,如果我们有序列 {10,22,9,33,21,50,41,60}, 最长上升子序列是 {10,22,33,50,60}。
#### 解决方案
cpp#include <iostream>
#include <vector>
int lis(const std::vector<int>& arr) {
int n = arr.size();
if (n ==0)
return0;
// dp[i] 表示以 arr[i] 结尾的最长上升子序列长度 std::vector<int> dp(n,1);
for (int i =1; i < n; ++i) {
for (int j =0; j < i; ++j) {
if (arr[i] > arr[j])
dp[i] = std::max(dp[i], dp[j] +1);
}
}
int maxLis =0;
for (const auto& val : dp)
maxLis = std::max(maxLis, val);
return maxLis;
}
int main() {
std::vector<int> arr = {10,22,9,33,21,50,41,60};
int result = lis(arr);
std::cout << "最长上升子序列长度:" << result << std::endl;
return0;
}
###2. 最短路径(Shortest Path)
最短路径问题是指在一个图中找到从源点到目标点的最短路径。例如,如果我们有一个图 {A, B, C, D},其中 A 和 B 相邻,B 和 C 相邻,C 和 D 相邻,我们需要找到从 A 到 D 的最短路径。
#### 解决方案
cpp#include <iostream>
#include <vector>
struct Edge {
int v;
int w;
};
bool bellmanFord(const std::vector<Edge>& edges, int n, int src) {
// dist[i] 表示源点到 i 的距离 std::vector<int> dist(n +1, INT_MAX);
dist[src] =0;
for (int i =0; i < n -1; ++i) {
for (const auto& edge : edges) {
if (dist[edge.v] != INT_MAX && dist[edge.v] + edge.w < dist[edge.u]) {
dist[edge.u] = dist[edge.v] + edge.w;
}
}
}
// 检查是否有负权重环 for (const auto& edge : edges) {
if (dist[edge.v] != INT_MAX && dist[edge.v] + edge.w < dist[edge.u]) {
return false; // 有负权重环 }
}
return true;
}
int main() {
int n =4;
std::vector<Edge> edges = {{0,5}, {1, -3}, {2,7}, {3,6}};
int src =0;
bool result = bellmanFord(edges, n, src);
if (result)
std::cout << "没有负权重环" << std::endl;
else std::cout << "有负权重环" << std::endl;
return0;
}
###3. 最大子矩阵和(Maximum Submatrix Sum)
最大子矩阵和问题是指在一个矩阵中找到一个子矩阵,使得该子矩阵的元素之和最大。例如,如果我们有矩阵 {1,2, -1, -4}, {-5, -3,9,7}, {10,11, -2,8},我们需要找到一个子矩阵,使得该子矩阵的元素之和最大。
#### 解决方案
cpp#include <iostream>
#include <vector>
int maxSubmatrixSum(const std::vector<std::vector<int>>& matrix) {
int n = matrix.size();
if (n ==0)
return0;
int m = matrix[0].size();
// dp[i][j] 表示以 matrix[i][j] 结尾的最大子矩阵和 std::vector<std::vector<int>> dp(n, std::vector<int>(m, INT_MIN));
for (int i =0; i < n; ++i) {
for (int j =0; j < m; ++j) {
if (i ==0 && j ==0)
dp[i][j] = matrix[i][j];
else if (i ==0)
dp[i][j] = std::max(matrix[i][j], dp[i][j -1]);
else if (j ==0)
dp[i][j] = std::max(matrix[i][j], dp[i -1][j]);
else dp[i][j] = std::max(std::max(dp[i -1][j], dp[i][j -1]), matrix[i][j] + dp[i -1][j -1]);
}
}
int maxSum = INT_MIN;
for (const auto& row : dp)
for (int val : row)
maxSum = std::max(maxSum, val);
return maxSum;
}
int main() {
std::vector<std::vector<int>> matrix = {{1,2, -1, -4}, {-5, -3,9,7}, {10,11, -2,8}};
int result = maxSubmatrixSum(matrix);
std::cout << "最大子矩阵和:" << result << std::endl;
return0;
}
上述问题都是动态规划路径问题的经典例子。通过使用动态规划技巧,我们可以有效地解决这些问题,得到最优解。
**参考**
* [Wikipedia: Dynamic Programming]( />* [GeeksforGeeks: Dynamic Programming]( />* [LeetCode: Dynamic Programming](

