Given an array of n numbers, our task is to calculate the maximum subarray sum. from《编程珠玑》

  1. //举例
  2. -1 2 4 -3 5 2 -5 2
  3. //最大子段和是10
  4. 2 4 -3 5 2

算法1,O(n^3)

  1. int best = 0;
  2. for (int a = 0; a < n; a++) {
  3. for (int b = a; b < n; b++) {
  4. int sum = 0;
  5. for (int k = a; k <= b; k++) {
  6. sum += array[k];
  7. }
  8. best = max(best,sum);
  9. }
  10. }
  11. cout << best << "\n";

算法2,O(n^2)

  1. int best = 0;
  2. for (int a = 0; a < n; a++) {
  3. int sum = 0;
  4. for (int b = a; b < n; b++) {
  5. sum += array[b];
  6. best = max(best,sum);
  7. }
  8. }
  9. 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. 1. The subarray only contains the element at position k.
  2. 2. The subarray consists of a subarray that ends at position k 1,
  3. 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.

  1. int best = 0, sum = 0;
  2. for (int k = 0; k < n; k++) {
  3. sum = max(array[k],sum+array[k]);
  4. best = max(best,sum);
  5. }
  6. cout << best << "\n";

aha,这是就是动态规划..

所以,你会了一个经典dp问题 当有人把动态规划认为是学习算法的里程碑,或者分水岭,此时,你已经悄然渡过


  1. // 另外一种,最大字段和的写法
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. int a[20], n;
  5. int main()
  6. {
  7. cin >> n;
  8. for (int i = 1; i <= n; i++) cin >> a[i];
  9. int maxn = -0x3f3f3f3f, area = 0;
  10. for (int i = 1; i <= n; i++){
  11. area += a[i];
  12. if (area > maxn) maxn = area;
  13. if (area < 0) area = 0; //另起炉灶
  14. }
  15. cout << maxn << '\n';
  16. return 0;
  17. }
  18. =================
  19. #include <bits/stdc++.h>
  20. using namespace std;
  21. int a[20], n;
  22. int dp[20];
  23. int maxn = -0x3f3f3f3f;
  24. int main()
  25. {
  26. cin >> n;
  27. for (int i = 1; i <= n; i++) cin >> a[i];
  28. for (int i = 1; i <= n; i++){
  29. dp[i] = max(dp[i - 1], 0) + a[i]; //另起炉灶
  30. maxn = max(maxn, dp[i]);
  31. }
  32. cout << maxn << '\n';
  33. return 0;
  34. }