實驗專案4———最大子段和問題
**:《發現這個博主的**實在是太棒了》
1.問題分析: 給定由n個整數(可能有負整數)組成的序列
2.演算法設計思路
暴力法: 對於起點 i,遍歷所有長度為1,2,…,n-i+1的子區間和,遍歷所有的字段,找出最大欄位和。
分治演算法:求解區間及其最大和,從結構上是非常適合分治法的,因為所有的子區間[start,end]之可能有以下三種可能性:
1.在【1,n/2】這個區域
2.在【n/2+1,n】這個區域
3.起點位於【1,n/2】,終點【n/2+1,n】區域
以上三種情形的最大值,就是所求的內容,前面兩種情形符合子問題遞迴的特性,所以遞迴可以求出,對於第三者情形,則必然包括了n/2和n/2+1兩個位置,這樣就可以利用第二種窮舉的思路分別向左右擴張求出
動態規劃:擴充套件到二維空間令b[j]表示以位置 j 為終點的所有子區間中和最大的一 個子問題:如j為終點的最大子區間包含了位置j-1,則以j-1為終點的最 大子區間必然包括在其中,如果b[j-1] >0, 那麼顯然b[j] = b[j-1] + a[j],用之前最大的乙個加上a[j]即可,因為a[j]必須包含;如果 b[j-1]<=0,那麼b[j] = a[j] ,因為既然最大,前面的負數必然不能使你 更大。
3.演算法實現1.暴力法:
#includeusing namespace std;
int maxsum(int a,int n,int &besti,int &bestj)}}
return sum;
}int main()
int s2=0;
int rights=0;
for(int i=center+1;i<=right;i++)
sum=s1+s2;
if(sum>n;
cout
int b[100];
for(m=0;m
3.動態規劃法:
#includeusing namespace std;
int maxsubsum(int a,int left,int right)
int s2=0;
int rights=0;
for(int i=center+1;i<=right;i++)
sum=s1+s2;
if(sum>n;
cout
int b[100];
for(m=0;m4.執行結果(截圖)
1.暴力法執行截圖:
2.分治法執行截圖:
3.動態規劃法執行截圖:
5.演算法分析
暴力法:
經過兩次巢狀迴圈時間複雜度:o(n2)
分治演算法:
每遞迴一次需logn,全部需要n次運算量,時間複雜度:o(nlogn)
動態規劃演算法:
只經歷了一次迴圈,時間複雜度:o(n)
6.經驗歸納與總結
通過時間複雜度的分析和實驗結果可以看出各演算法的好壞依次是動態規劃演算法、分治演算法,bf演算法,當資料較小時各演算法之間的差距並不大,甚至有時bf演算法還優於分治,而且資料越大,bf演算法的缺點越明顯,與動態規劃的差距越大。
最大子段和問題 蠻力法 分治法 動態規劃法
蠻力法 int maxsum1 int a,int n return maxsum 分治法 int maxsum2 int left,int right,int a sum 0 right max 0 求右邊的最大值 for i center 1 i right i sum right max le...
動態規劃法求解RMQ
題目描述 思路分析 下面把sparse table演算法分成預處理和查詢兩部分來說明 以求最小值為例 預處理 預處理使用dp的思想,f i,j 表示 i,i 2 j 1 區間中的最小值,我們可以開闢乙個陣列專門來儲存f i,j 的值。例如,f 0,0 表示 0,0 之間的最小值,就是num 0 f ...
斐波那契數 動態規劃法和分治法
這個學期開了一門叫演算法的課,為了今天的 複賽,這兩天研究了一下這門課。感覺演算法真的是太神奇了。就比如說今天學了動態規劃 小小的入門 用它實現了斐波那契數,和原來的用分治法的一比較,差距出來了。相差十幾幾萬倍 要算的數越大相差的倍數越多 下面是實現 include include using na...