動態規劃演算法
給定整數序列a1
,a2,
...,
an,求該序列形如∑j
k=ia
k 子串行和的最大值: ma
x 運用分治法求解最大子段和問題。將原序列劃分為兩個規模盡量相等的子串行,設劃分的中間位置為 mid,則原問題最大子段和包含的序列必然為下列 3 種情況之一:
左側:完全位於序列a1
,...
,ami
d 中
右側:完全位於序列am
id+1
,...
,an 中
跨越兩側:位於序列ai
,...
,aj 中,其中1≤
i≤mi
d≤j≤
n 那麼最大子段和即為這三個區間的最大子段和的最大值。因此原問題可化為兩個求解規模為 n/2 的子問題,和求解乙個跨越中點的序列的最大子段和問題。其中第三種情況可分別求解序列 a1
,...
,ami
d 和 am
id+1
,...
,an 的最大子串行,然後將兩者合併即可,因此該部分的時間複雜度為 θ(n)。演算法的時間複雜度可用遞迴的形式表示為: t(
n)=;
/***********find the max array in the interval [i...mid...j]***********/
subarray maxcrossarray(vector
data, int low, int mid, int high)
}sum = 0;
int sumrifgt = -int_max;
for (int j = mid + 1; j < high+1; j++)
}sa.sum = sumleft + sumrifgt;
return sa;
}/**********divide and conquer algorithm**********/
subarray find(vector
data, int low, int high)
else
else
}}最大子段和問題具有最優子結構性質。取規模為n的整數序列的子結構為a1
,...
,an−
1 ,則原序列的最大子段和包含的序列要麼是子結構的最大欄位和序列,要麼是ai
,...
,an−
1,an
,其中1≤
i≤n 。因此原問題的解可由子結構的解得到,具有最優子結構性質。
時間複雜度:已知序列a1
,..,
aj的最大子段和序列a(m,n),並記錄形如a1
,...
,aj 中的最大子段和序列a(i,j),求解序列a1
,...
,aj+
1 時,只需求解ma
x ,即可得到新問題的解。設原問題的規模為n,則該演算法的時間複雜度為θ(
n),具有線性複雜度。
**實現
/*********dynamic programming algorithm*********/
subarray dp(vector
data, int low, int high)
;subarray saright = pre;
for (int i = low + 1; i < high + 1; i++)
else
if (saright.sum >= pre.sum)
}return pre;
}
暴力法 分治法 動態規劃法求解最大欄位和
實驗專案4 最大子段和問題 發現這個博主的 實在是太棒了 1.問題分析 給定由n個整數 可能有負整數 組成的序列 2.演算法設計思路 暴力法 對於起點 i,遍歷所有長度為1,2,n i 1的子區間和,遍歷所有的字段,找出最大欄位和。分治演算法 求解區間及其最大和,從結構上是非常適合分治法的,因為所有...
分治和動態規劃
分治和動態規劃都是解決較大規模問題比較困難或者無法直接求解的場景下的策略,兩者之間有相同點,也有不同點。相同點 1 原問題需要具有最優子結構性質 2 解決思路都是將原問題分解成若干個規模較小的子問題。不同點 1 分治法要求子問題之間相互獨立,子問題的分解中不能包含公共子問題 2 動態規劃是應對子問題...
分治法 動態規劃 最大子段和
題目 給定n個整數 可能為負整數 組成的序列a1,a2,a3,a4,a5,an,求該序列子段和的最大值,子段和 定義為連續 下標遞增 的元素之和。當所有的整數均為負整數時定義其最大子段和為0。如序列為時,最大子段和為20。該問題可以用分治法或者動態規劃來求解。下面給出兩種演算法的思路及 實現 思路 ...