牛客习题:线性动态规划 (mari 和 shiny)C++ 实现
线性动态规划是一种解决优化问题的常用方法,特别是在问题具有重叠子问题和最优子结构性质的时候。在这里,我将展示如何使用C++实现一个基本的线性动态规划问题。
假设我们有一个简单的线性动态规划问题:给定一个数组arr
,找到能够获得的最大子数组和。这个问题可以用动态规划来解决,下面是C++的实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Function to find the maximum sum of a contiguous subarray
int maxSubArraySum(const vector<int>& arr) {
if (arr.empty()) {
return 0; // Return 0 if the array is empty
}
int n = arr.size();
// dp[i] will store the maximum subarray sum ending at index i
vector<int> dp(n);
dp[0] = arr[0]; // Base case
int maxSum = dp[0]; // Initialize maxSum with the base case result
for (int i = 1; i < n; ++i) {
// Recurrence relation: maximum of continuing the previous subarray or starting a new subarray
dp[i] = max(arr[i], dp[i-1] + arr[i]);
// Update maxSum if the current dp[i] is greater
maxSum = max(maxSum, dp[i]);
}
return maxSum;
}
int main() {
vector<int> arr = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
int result = maxSubArraySum(arr);
cout << "The maximum sum of a contiguous subarray is: " << result << endl;
return 0;
}
代码解释:
初始化:我们首先检查数组是否为空,然后初始化
dp
数组来存储到当前位为止的最大子数组和,并将maxSum
初始化为第一个元素的值。递推式:对于每一个元素,计算是延续之前的子数组还是从新元素开始新的子数组。递推式为:
dp[i] = max(arr[i], dp[i-1] + arr[i])
更新最大值:在每一步更新
maxSum
,以便始终保存全局最大子数组和。时间复杂度和空间复杂度:此实现的时间复杂度为O(n),空间复杂度为O(n)。如果想进一步减小空间复杂度,可以优化成O(1),因为我们只需要前一个状态值来计算当前状态。
这种方法可以被用于许多类似的线性动态规划问题,根据不同问题特性稍作改动。