Given an array of n numbers, our task is to calculate the maximum subarray sum. from《编程珠玑》
//举例-1 2 4 -3 5 2 -5 2//最大子段和是102 4 -3 5 2
算法1,O(n^3)
int best = 0;for (int a = 0; a < n; a++) {for (int b = a; b < n; b++) {int sum = 0;for (int k = a; k <= b; k++) {sum += array[k];}best = max(best,sum);}}cout << best << "\n";
算法2,O(n^2)
int best = 0;for (int a = 0; a < n; a++) {int sum = 0;for (int b = a; b < n; b++) {sum += array[b];best = max(best,sum);}}cout << best << "\n";
算法3,O(n)
Consider the subproblem of finding the maximum-sum subarray that ends at position k. There are two possibilities:
1. The subarray only contains the element at position k.2. The subarray consists of a subarray that ends at position k − 1,followed by the element at position k.
In the latter case, since we want to find a subarray with maximum sum, the subarray that ends at position k − 1 should also have the maximum sum. Thus, we can solve the problem efficiently by calculating the maximum subarray sum for each ending position from left to right.
int best = 0, sum = 0;for (int k = 0; k < n; k++) {sum = max(array[k],sum+array[k]);best = max(best,sum);}cout << best << "\n";
aha,这是就是动态规划..
所以,你会了一个经典dp问题 当有人把动态规划认为是学习算法的里程碑,或者分水岭,此时,你已经悄然渡过
// 另外一种,最大字段和的写法#include <bits/stdc++.h>using namespace std;int a[20], n;int main(){cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];int maxn = -0x3f3f3f3f, area = 0;for (int i = 1; i <= n; i++){area += a[i];if (area > maxn) maxn = area;if (area < 0) area = 0; //另起炉灶}cout << maxn << '\n';return 0;}=================#include <bits/stdc++.h>using namespace std;int a[20], n;int dp[20];int maxn = -0x3f3f3f3f;int main(){cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];for (int i = 1; i <= n; i++){dp[i] = max(dp[i - 1], 0) + a[i]; //另起炉灶maxn = max(maxn, dp[i]);}cout << maxn << '\n';return 0;}
