题目来自网络
题目:给定数组,求其 最大的子序列积以及对应的区间
举例:数组{1,2,-8,12,7}的最大的子序列积为84,其区间为[3,4]
思路:可以使用动态规划求解,具体与绝对值最大的子序列和以及其区间的思路一样.也需要考虑负值。
代码:只求最大子序列积,不求解区间
#include <iostream>
#include <assert.h>
using namespace std;
//Max[i] = max(nArr[i],Max[i - 1] * nArr[i],Min[i - 1] * nArr[i])
//Min[i] = min(nArr[i],Max[i - 1] * nArr[i],Min[i - 1] * nArr[i]);
//初始化
//Max[0] = nArr[0]
//Min[0] = nArr[0]
int Max(int x,int y,int z)
{
if (x > y)
{
if (x > z)
{
return x;
}
else
{
return z;
}
}
else
{
if (y > z)
{
return y;
}
else
{
return z;
}
}
}
int Min(int x,int y,int z)
{
if (x < y)
{
if (x < z)
{
return x;
}
else
{
return z;
}
}
else
{
if (y > z)
{
return z;
}
else
{
return y;
}
}
}
int MaxSubProduct(int arr[],int nLen)
{
int MaxProduct[100];
int MinProduct[100];
int nMaxSubProduct;
MaxProduct[0] = arr[0];
MinProduct[0] = arr[0];
nMaxSubProduct = arr[0];
for (int i = 1;i < nLen;i++)
{
MaxProduct[i] = Max(arr[i],MaxProduct[i - 1] * arr[i],MinProduct[i - 1] * arr[i]);
MinProduct[i] = Min(arr[i],MaxProduct[i - 1] * arr[i],MinProduct[i - 1] * arr[i]);
if (MaxProduct[i] > nMaxSubProduct)
{
nMaxSubProduct = MaxProduct[i];
}
if (MinProduct[i] > nMaxSubProduct)
{
nMaxSubProduct = MinProduct[i];
}
}
return nMaxSubProduct;
}
int main()
{
int arr[8] = {4,-3,5,-2,-1,2,6,-2};
int nLen = 8;
cout<<MaxSubProduct(arr,nLen)<<endl;
int arr1[1] = {-5};
int nLen1 = 1;
cout<<MaxSubProduct(arr1,nLen1)<<endl;
int arr2[2] = {0,-5};
int nLen2 = 2;
cout<<MaxSubProduct(arr2,nLen2)<<endl;
int arr3[6] = {-5,4,-20,16,-2,-3};
int nLen3 = 6;
cout<<MaxSubProduct(arr3,nLen3)<<endl;
int arr4[2] = {-5,0};
int nLen4 = 2;
cout<<MaxSubProduct(arr4,nLen4)<<endl;
int arr5[4] = {-5,0,-3,2};
int nLen5 = 4;
cout<<MaxSubProduct(arr5,nLen5)<<endl;
system("pause");
return 1;
}
由于求解以第i个为止的最大子序列之积时,只用到第i - 1个状态。因此可以不用数组保存状态,而用变量保存。
代码:只求最大子序列积,不求解区间 + 使用变量保存状态
#include <iostream>
#include <assert.h>
using namespace std;
//Max = max(nArr[i],Max * nArr[i],Min * nArr[i])
//Min = min(nArr[i],Max * nArr[i],Min * nArr[i]);
//初始化
//Max = nArr[0]
//Min = nArr[0]
int Max(int x,int y,int z)
{
if (x > y)
{
if (x > z)
{
return x;
}
else
{
return z;
}
}
else
{
if (y > z)
{
return y;
}
else
{
return z;
}
}
}
int Min(int x,int y,int z)
{
if (x < y)
{
if (x < z)
{
return x;
}
else
{
return z;
}
}
else
{
if (y > z)
{
return z;
}
else
{
return y;
}
}
}
int MaxSubProduct(int arr[],int nLen)
{
int nMaxTmp = 0;
int nMinTmp = 0;
int MaxProduct = arr[0];
int MinProduct = arr[0];
int nMaxSubProduct = arr[0];
for (int i = 1;i < nLen;i++)
{
nMaxTmp = MaxProduct * arr[i];
nMinTmp = MinProduct * arr[i];
MaxProduct = Max(arr[i],nMaxTmp,nMinTmp);
MinProduct = Min(arr[i],nMaxTmp,nMinTmp);
if (MaxProduct > nMaxSubProduct)
{
nMaxSubProduct = MaxProduct;
}
if (MinProduct > nMaxSubProduct)
{
nMaxSubProduct = MinProduct;
}
}
return nMaxSubProduct;
}
代码:求最大子序列积 + 求解区间 + 使用变量保存状态
#include <iostream>
#include <assert.h>
using namespace std;
//Max = max(nArr[i],Max * nArr[i],Min * nArr[i])
//Min = min(nArr[i],Max * nArr[i],Min * nArr[i]);
//初始化
//Max = nArr[0]
//Min = nArr[0]
int MaxSubProduct(int arr[],int nLen)
{
int nMaxTmp = 0;
int nMinTmp = 0;
int MaxProduct = arr[0];
int MinProduct = arr[0];
int nMaxSubProduct = arr[0];
//--区间
int nCurMaxStart = 0;
int nCurMinStart = 0;
int nMaxStart = 0;
int nMaxEnd = 0;
int nTmp = 0;
for (int i = 1;i < nLen;i++)
{
nMaxTmp = MaxProduct * arr[i];
nMinTmp = MinProduct * arr[i];
if (nMaxTmp > nMinTmp)
{
MaxProduct = nMaxTmp;
MinProduct = nMinTmp;
}
else
{
MaxProduct = nMinTmp;
MinProduct = nMaxTmp;
//设置区间
//nCurMaxStart始终指向最大乘积下标起点
//nCurMinStart始终指向最小乘积下标起点
nTmp = nCurMaxStart;
nCurMaxStart = nCurMinStart;
nCurMinStart = nTmp;
}
if (MaxProduct <= arr[i])//别忘了=
{
MaxProduct = arr[i];
//区间
nCurMaxStart = i;
}
if (MinProduct >= arr[i])
{
MinProduct = arr[i];
//区间
nCurMinStart = i;
}
if (MaxProduct > nMaxSubProduct)
{
nMaxSubProduct = MaxProduct;
//区间
nMaxStart = nCurMaxStart;
nMaxEnd = i;
}
if (MinProduct > nMaxSubProduct)
{
nMaxSubProduct = MinProduct;
//区间
nMaxStart = nCurMinStart;
nMaxEnd = i;
}
}
cout<<"区间: "<<nMaxStart<<" - "<<nMaxEnd<<endl;
return nMaxSubProduct;
}
int main()
{
// int arr[8] = {4,-3,5,-2,-1,2,6,-2};
// int nLen = 8;
// cout<<MaxSubProduct(arr,nLen)<<endl;
// int arr2[8] = {-3,0,-8,-2,0,-12,-13,0};
// int nLen = 8;
// cout<<MaxSubProduct(arr2,nLen)<<endl;
// int arr[5] = {1,2,-8,12,7};
// int nLen = 5;
// cout<<MaxSubProduct(arr,nLen)<<endl;
// int arr2[5] = {0,-1,2,3,0};
// int nLen = 5;
// cout<<MaxSubProduct(arr2,nLen)<<endl;
// int arr2[2] = {1,2};
// int nLen = 2;
// cout<<MaxSubProduct(arr2,nLen)<<endl;
system("pause");
return 1;
}