NC83 子数组最大乘积
本题要求最大子序积,是【最大子序和】的加强版,动态规划是最优解法。
在最大子序和中,状态转移方程为:
f(i)=max{f(i−1)+arr[i], arr[i]}
f(i)是数组的局部最大子序和,求出最大的f(i)即可。
最大子序积中,需要考虑负数的问题,因为一个负数乘以一个负数可能会变为最大值。于是我们维护局部最大值fmax(i)和局部最小值fmin(i),状态转移方程如下:
fmax(i) = max{fmax(i-1)*arr[i], fmin(i-1)*arr[i], arr[i]}
fmin(i) = min{fmin(i-1)*arr[i], fmax(i-1)*arr[i], arr[i]}
class Solution {
public:
double maxProduct(vector<double> arr) {
vector<double> dpMax(arr.size()+5);
vector<double> dpMin(arr.size()+5);
//一定要注意这里,因为是子数组,必须要包含一个。
dpMax[0]= arr[0];
dpMin[0]= arr[0];
double Max=-100000000;
Max=dpMax[0];
// cout<<Max<<endl;
for(int i=1;i<arr.size();i++)
{
if(arr[i]>0)
{
dpMax[i]=max(arr[i],dpMax[i-1]*arr[i]);
dpMin[i]=min(arr[i],dpMin[i-1]*arr[i]);
}
else
{
dpMax[i]=max(arr[i],dpMin[i-1]*arr[i]);
dpMin[i]=min(arr[i],dpMax[i-1]*arr[i]);
}
Max=max(dpMax[i],Max);
}
return Max;
}
};