标签:
问题:给定一个数组a[0,...,n-1],求a的连续子数组,使得该子数组的和最大。
例如:
数组:1,-2,3,10,-4,7,2,-5;
最大子数组:3,10,-4,7,2
结果为:18
首先是暴力法:
1 //暴力法 2 int MaxSubArry(int *a, int n) 3 { 4 int maxsum = a[0]; 5 int currsum; 6 for(int i = 0; i < n; ++i) 7 { 8 for(int j = i; j < n; ++j) 9 { 10 currsum = 0; 11 for(int k = i; k < j; ++k) 12 { 13 currsum += a[k]; 14 } 15 if(currsum >= maxsum) 16 { 17 maxsum = currsum; 18 } 19 } 20 } 21 return maxsum; 22 }
然后是分治法
//分治法 23 int MaxSubArry(int *a, int from, int to) 24 { 25 //递归基 26 if(from == to) 27 return a[from]; 28 int middle = (from + to)/2; 29 int m1 = MaxSubArry(a, from, middle); 30 int m2 = MaxSubArry(a, middle + 1, to); 31 int i, left = a[middle], now = a[middle]; 32 for(i = middle - 1; i > from; --i) 33 { 34 now += a[i]; 35 if(now > left) 36 { 37 left = now; 38 } 39 } 40 int right = a[middle + 1]; 41 now = a[middle + 1]; 42 for(i = middle + 2; i < to; ++i) 43 { 44 now += a[i]; 45 if(now > right) 46 { 47 right = now; 48 } 49 } 50 int m3 = left + right; 51 return Max(m1, m2, m3);//求三者最大那个 52 }
最后是动态规划的方法:
//动态规划 //记S[i]为以a[i]结尾的数组中和最大的子数组 21 int MaxSubArry(int *a, int *s, int n) 22 { 23 int result = a[0]; 24 int sum = a[0]; 25 s[0] = a[0]; 26 for(int i = 1; i < n; ++i) 27 { 28 if(sum > 0) 29 { 30 sum += a[i]; 31 s[i] = sum; 32 } 33 else{ 34 result = sum + a[i]; 35 if(result > a[i]) 36 { 37 s[i] = result; 38 sum = result; 39 }else 40 { 41 s[i] = a[i]; 42 sum = a[i]; 43 } 44 } 45 } 46 return Max(s, n); //求s中最大的那个元素 47 }
时间复杂度分别为大On^3, 大Onlogn,大On
标签:
原文地址:http://www.cnblogs.com/bigshowxin/p/4398665.html