最大子序列和的探讨

来源:互联网 发布:java bigdecimal 长度 编辑:程序博客网 时间:2024/05/21 10:29
/**最大子序列和的探讨Made by Bruth-Lee*/#include<iostream>using namespace std;int MaxsubseqSum1(int A[], int N)//此方法暴力枚举了所有情况,复杂度为O(N的3次方){int ThisSum, MaxSum = 0, i, j, k;for (i = 0; i < N; i++){for (j = i; j < N; j++){ThisSum = 0;for (k = i; k <= j; k++){ThisSum += A[k];}if (ThisSum > MaxSum){MaxSum = ThisSum;}}}return MaxSum;}//上述方法浪费时间的原因在于做了不必要的重复计算,So,第二种方法将作出修正int MaxsubseqSum2(int A[], int N){int ThisSum, MaxSum = 0;int i, j;for (i = 0; i < N; i++){ThisSum = 0;for (j = i; j < N; j++){ThisSum += A[j];if (ThisSum > MaxSum)MaxSum = ThisSum;}}return MaxSum;}//此方法在第一个的基础上对速率做了很大改进,复杂度为O(N的平方),但还不是最优的。下面看第三种方法int Max(int x, int y, int z){if (x > y){if (x > z) return x;else return z;}else if (y < z){return z;}else return y;}int DivideAndConquer(int A[], int left, int right){int MaxleftSum=0, MaxrightSum=0;int leftBoardSum, rightBoardSum;int MaxleftBoardSum, MaxrightBoardSum;int center, i;//递归终止条件if (right == left){if (A[left] > 0) return A[left];else return 0;}center = (right + left) / 2;DivideAndConquer(A, left, center);DivideAndConquer(A, center + 1, right);MaxleftBoardSum = 0, leftBoardSum = 0;for (i = center; i >= left; i--){leftBoardSum += A[i];if (leftBoardSum > MaxleftBoardSum) MaxleftBoardSum = leftBoardSum;}MaxrightBoardSum = 0, rightBoardSum = 0;for (i = center + 1; i <= right; i++){rightBoardSum += A[i];if (rightBoardSum > MaxrightBoardSum)MaxrightBoardSum = rightBoardSum;}return Max(MaxleftSum, MaxrightSum, MaxleftBoardSum + MaxrightBoardSum);}//该方法代码较为复杂//该思想为分而治之,将数列一分为二,把问题化为三种情况,一:左序列额的和,二:右序列的和,三:跨越中介的和,最后再取三者最大的;复杂度为N*logN;但是这还并不是最优的,请往下看;//online_processingint MaxsubseqSum3(int A[], int N){int i;int ThisSum = 0;int MaxSum = 0;for (i = 0; i < N; i++){ThisSum += A[i];//向右累加if (ThisSum > MaxSum) MaxSum = ThisSum;//更新最大的MaxSumelse if (ThisSum < 0)ThisSum = 0;//当累加的和为负数时,即不会使后面的值变大,抛弃;}return MaxSum;}//在线处理的方式兼具低复杂度O(N)和代码简洁,即不占用太多的空间,也不消耗太多的时间,是本题的最优解int main(){int A[1000],i, N;while (cin>>N)//输入5{for (i = 0; i < N; i++)//输入-1 3 0 6 5{cin >> A[i];}cout << "------ 暴力方法------" << endl;cout << MaxsubseqSum1(A, N)<<endl;cout << "-------稍暴方法------" << endl;cout << MaxsubseqSum2(A, N) << endl;cout <<"--------精英方法-------"<<endl;cout << DivideAndConquer(A, 0, N - 1)<<endl;cout <<"--------大师方法-------"<< endl;cout << MaxsubseqSum3(A, N) << endl;}return 0;}//结果为14

原创粉丝点击