最简单粗暴的最大连续和
c
#include <stdio.h> #include <string.h> int main() { const int maxn = 1000; int n; int S[maxn]; while(~scanf("%d", &n)) { memset(S, 0, sizeof(S)); for(int i = 1 ; i <= n; i++) scanf("%d", &S[i]); int best = S[1]; for(int i = 1; i <= n; i++) for(int j = i; j <= n; j++) { int sum = 0; for(int k = i; k <= j ; k++) { sum += S[k]; } best = best > sum ? best : sum; } printf("%d\n", best); } return 0; }
优化。
8.1.1 渐进时间复杂度
渐进时间复杂度计算方法,如何估算时间复杂度。
直接求所有的和,通过和的加减求区间和。
- 最大连续和
c
#include <stdio.h> #include <string.h> int main() { const int maxn = 1000; int n; int S[maxn]; while(~scanf("%d", &n)) { int temp; memset(S, 0, sizeof(S)); for(int i = 1 ; i <= n; i++) { scanf("%d", &temp); S[i] = S[i-1] + temp; } int best; for(int i = 0; i <= n; i++) for(int j = i; j <= n; j++) { int temp = S[j] - S[i] ; best = best > temp ? best : temp; } printf("%d\n", best); } return 0; }
8.1.3 分治法
c
#include <stdio.h> #include <string.h> int maxsum(int *A, int x, int y) { int i, m, v, L, R, max; if(y - x == 1) return A[x]; m = x + (y-x)/2; int a, b; // 求左右最大值 a = maxsum(A, x, m); b = maxsum(A, m, y); max = a > b ? a : b; // 左右分别占一部分 v = 0; L = A[m-1]; for(i = m-1; i >= x; i--) { v += A[i]; L = L > v ? L : v; } v = 0; R = A[m]; for(i = m; i < y; i++) { v += A[i]; R = R > v? R : v; } return max > (L+R) ? max : (L+R); } const int maxn =1000; int main() { int a[maxn]; int n; int i; while(~scanf("%d", &n)) { for (i = 0; i < n; i++) scanf("%d", &a[i]); printf("%d\n", maxsum(a, 0, n)); } return 0; }
动态规划的思想
如果找S[j] - S[i-1]
的最大值,就是找S[i-1]
的最小。因此只用扫描一次数组。
c
#include <stdio.h> #include <string.h> const int maxn =1000; const int INF = 0x3f3f3f3f; int main() { int a[maxn], s[maxn]; int n, i, min, max, temp; while(~scanf("%d", &n)) { for(i = 1; i <= n; i++) scanf("%d", &a[i]); max = min = s[0] = 0; for(int i = 1; i <= n; i++) { s[i] = s[i-1] + a[i]; temp = s[i] - min; if(temp < 0) min = s[i]; else max = max > temp ? max : temp; } printf("%d\n", max); } return 0; }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。