標籤:最大連續乘積子串 動態規劃 狀態轉移方程 時間複雜度
動態規劃題目(三)——最大連續乘積子串
1. 題目描述
給一個浮點數序列,取最大乘積連續子串的值,例如 -2.5,4,0,3,0.5,8,-1,則取出的最大乘積連續子串為3,0.5,8。也就是說,上述數組中,3 0.5 8這3個數的乘積30.58=12是最大的,而且是連續的。
2. 動態規劃求解
動態規劃求解題目的時候最重要的是要找到狀態轉移方程!
針對這道題目,我們使用兩個變數記錄當前最大值maxEnd, 和當前最小值minEnd。為什麼記錄當前最小值呢?因為數組中會出現負數,乘以一個負數的話,當前最小值是會逆襲的!!
然後就是狀態轉移方程中對這兩個變數的更新:
maxEnd=max(max(maxEnd*a[i], minEnd*a[i]), a[i]); //更新當前最大值
minEnd=min(min(maxEnd*a[i], minEnd*a[i]), a[i]); //更新當前最小值
下面的解法時間複雜度為O(n)。
代碼如下:
#include<iostream>#include<algorithm>#define max(a, b) (((a) > (b)) ? (a) : (b)) //宏定義,注意加括弧#define min(a, b) (((a) < (b)) ? (a) : (b))using namespace std; double findMaxProduct(double *a, int num){double maxProduct=a[0]; double maxEnd=a[0]; //記錄當前最大值double minEnd=a[0]; //記錄當前最小值,因為後面會出現負數的話,當前的最小值就會逆襲~!for (int i=1; i<num; i++){maxEnd=max(max(maxEnd*a[i], minEnd*a[i]), a[i]); //更新當前最大值minEnd=min(min(maxEnd*a[i], minEnd*a[i]), a[i]); //更新當前最小值maxProduct=max(maxEnd, maxProduct); //乘積最大值一定是二選一}return maxProduct; }int main(){double a[7]={-2.5, 4, 0, 3, 0.5, 8, -1}; int num=7; double maxProduct=findMaxProduct(a, num); cout<<maxProduct<<endl; }
動態規劃題目(三)——最大連續乘積子串