求最大子串行及其效率解析

2022-02-17 23:53:27 字數 3679 閱讀 2558

#include #include using namespace std;

//s(tart)表示最大子串行的開始位置,e(nd)表示結束位置

//這裡如果有多於乙個的最大子串行的時候,只記錄開始位置最低的那個

int s=0;

int e=0;

//窮舉法,複雜度o(n^3)

long maxsubsum1(const vector&a)

} }return maxsum;

}//也是窮舉法,不過減去了上面的一些不必要操作o(n^2)

long maxsubsum2(const vector&a)

} }return maxsum;

}long max3(long a, long b, long c)

long maxsumrec(const vectora, int left, int right)

int center=(left+right)/2;

long maxleftsum=maxsumrec(a,left,center);

long maxrightsum=maxsumrec(a,center+1,right);

//某段序列中,求含最右側元素序列和的最大值

long maxleftbordersum=0,leftbordersum=0;

for (int i=center; i>=left; i--) }

//某段序列中,求含最左側元素序列和的最大值

long maxrightbordersum=0,rightbordersum=0;

for (int j=center+1; j<=right; j++) }

return max3(maxleftsum,maxrightsum,

maxleftbordersum+maxrightbordersum);

}//該方法我們採用「分治策略」(divide-and-conquer),相對複雜的o(nlogn)的解法

//最大子串行可能在三個地方出現,或者在左半部,或者在右半部,

//或者跨越輸入資料的中部而佔據左右兩部分。前兩種情況遞迴求解,

//第三種情況的最大和可以通過求出前半部分最大和(包含前半部分最後乙個元素)

//以及後半部分最大和(包含後半部分的第乙個元素)相加而得到。

long maxsubsum3(const vector&a)

//如果a[i]是負數那麼它不可能代表最有序列的起點,因為任何包含a[i]的作為起點的子

//序列都可以通過用a[i+1]作為起點來改進。類似的有,任何的負的子串行不可能是最優

//子串行的字首。例如說,迴圈中我們檢測到從a[i]到a[j]的子串行是負數,那麼我們就可以推進i。

//關鍵的結論是我們不僅可以把i推進到i+1,而且我們實際可以把它一直推進到j+1。

long maxsubsum4(const vector&a)

else if(thissum<0)

} return maxsum;

}

測試程式:

#include #include #include #include #include #include using namespace std;

const long count = 1000;

const int max_num = 200;

int start = 0;

int end = 0;

bool readfile(vector&input, string filename)

int s;

while(infile >> s)

return true;

}bool writetestdata(string filename)

srand((unsigned)time(null));

for(int i = 0; i < count; i++)

else

if(thissum > maxsum)

}} return maxsum;

}long maxsubsum2(const vector& a)

} }return maxsum;

}long max3(long a, long b, long c)

if(a > c)

else }

long maxsumrec(const vector&a, int left, int right)

else return 0;

} int center = (left + right) / 2;

long maxleftsum = maxsumrec(a, left, center);

long maxrightsum = maxsumrec(a, center + 1, right);

long maxleftbordersum = 0, leftbordersum = 0;

for (int i = center; i >= left; i--) }

long maxrightbordersum = 0, rightbordersum = 0;

for(int j = center + 1; j <= right; j++) }

return max3(maxleftsum, maxrightsum, maxleftbordersum + maxrightbordersum);

}long maxsubsum3(const vector&a)

long maxsubsum4(const vector& a)

return maxsum;

}int main()

if(readfile(num, "in.txt"))

{ start = clock();

cout << maxsubsum1(num) << endl;

finish = clock();

//cout << "start position = " << start << "\t" << "start position = " << end <

count = 1000

4135

time used = 12.87

4135

time used = 0.06

4135

time used = 0.00

4135

time used = 0.00

請按任意鍵繼續. . .

count = 2000

8968

time used = 104.37

8968

time used = 0.23

8968

time used = 0.00

8968

time used = 0.00

請按任意鍵繼續. . .

count = 10000 //o(n^3)略去

15302

time used = 5.88

15302

time used = 0.02

15302

time used = 0.00

請按任意鍵繼續. . .

count = 100000

33853

time used = 570.03

33853

time used = 0.16

33853

time used = 0.01

請按任意鍵繼續. . .

求最大子串行

1.暴力求解,時間複雜度為n 3 int maxsubarray int a int n return maxsum 2.分治法 將陣列從中間分開,那麼最大子陣列要麼完全再左半邊陣列,要麼完全在右半邊陣列,要麼跨立在分界點上。完全在左陣列 右陣列遞迴解決。跨立在分界點上 實際上是左陣列的最大字尾和右...

求序列的最大子串行

看 程式設計珠璣 一書,講解求序列的最大子串行。問題 給定乙個實數序列x1,x2,xn 不必是正數 尋找乙個連續的子串行xi,x i 1 xj,使得其數值之和在所有連續子串行數值之和中是最大的。演算法1思路 比較所有連續序列數值的和,找到最大的。1.maxsofar 0 2.for i 0,n 3....

求最大子串行和

include using namespace std int maxseqsum const int a,int n o n 2 return s2 int maxseqsum2 const int a,int n o n else if s1 0 return s2 int maxseqsum3...