**如下:
#include using namespace std;
struct info
};class maxsubarrayproblem
info findcrosubarr(int low, int mid, int high)
} // right side max value
for (int i=mid+1; i<=high; ++i)
} // get and return crossing middle max value.
return info(lm+rm, lp, rp);
}};int main() ;
maxsubarrayproblem test(a, 16);
}
演算法分析:
分治遞迴策略。將陣列依次二分以縮減問題規模,拿第一次二分來說,如果整個陣列存在乙個最大子陣列,那麼它要麼在劃分後的左半部分,要麼在右半部分,要麼跨過中線,正是依據這個思路我們將問題一直縮減,縮減到單個元素時為base case。在一次劃分返回時,返回這三種情況中最大的值以及當前這乙個最大子陣列(不一定是全域性最大的)所覆蓋的範圍(下標起始位置與終止位置),最終在最後一次返回(也就是第一次劃分)時得到我們要的結果。
因為採用分治遞迴策略,演算法時間複雜度為o(nlgn)
**如下:
#include
using
namespace std;
class
dpfindmaxsubarr
void
dp_(
)void
showanswer()
};intmain()
;// 0 to 3 sum as 10
//int a;
dpfindmaxsubarr test
(a,16);
test.
dp_();
test.
showanswer()
;return0;
}
演算法分析:
最重要的是得出動態規劃演算法的核心:遞推表示式。
這裡表示式為,
dp[大致思路是如果當前元素加上前面傳過來的最大值大於0,那麼就加在一起(因為只要大於0那麼和我加在一起我肯定是比原來的值要大的);如果加在一起之後還沒有我本身大(也就是說傳過來乙個負數),那麼就拋棄這個數,自己和自己一起。i+i]
=max
(dp[
i]+a
[i+1
],a[
i+1]
);dp[i+i] = max(dp[i]+a[i+1], a[i+1]);
dp[i+i
]=ma
x(dp
[i]+
a[i+
1],a
[i+1]);
時間複雜度為線性o(n)。第一次掃一遍得到dp陣列,第二次掃dp陣列得到最大子陣列的範圍以及最大值。
難點在於如果定義dp陣列及其計算表示式
最大子陣列問題 動態規劃
昨天偶然上csdn,看到這個問題,學習了一種複雜度為o n 的演算法,可以計算array的最大子陣列問題。思路就是從0 length,將array累加起來,同時用乙個變數max記錄最大值,如果sum max,就更新max,如果sum 0 就令sum 0 為什麼是這樣呢,sum 0的話,前面的就可以直...
最大子段和 分治與動態規劃
問題 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為 max,1 i j n 例如,當 a1,a2,a3,a4,a4,a6 2,11,4,13,5,2 時,最大子...
最大子段和 分治與動態規劃
問題 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為 max,1 i j n 例如,當 a1,a2,a3,a4,a4,a6 2,11,4,13,5,2 時,最大子...