每日一题(51) - 最大子序列积以及区间
2013-07-24 21:18
218 查看
题目来自网络
题目:给定数组,求其 最大的子序列积以及对应的区间
举例:数组{1,2,-8,12,7}的最大的子序列积为84,其区间为[3,4]
思路:可以使用动态规划求解,具体与绝对值最大的子序列和以及其区间的思路一样.也需要考虑负值。
代码:只求最大子序列积,不求解区间
代码:只求最大子序列积,不求解区间 + 使用变量保存状态
代码:求最大子序列积 + 求解区间 +
使用变量保存状态
题目:给定数组,求其 最大的子序列积以及对应的区间
举例:数组{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; }
相关文章推荐
- 每日一题(50) - 绝对值最大的子序列和以及其区间
- 任意区间的最长连续递增子序列,最大连续子序列和
- 关于序列的面试题2------------最大连续子序列和以及积
- 51nod 1062 序列中最大的数 (打表,连续区间问题)
- 最大子序列和以及最大矩阵和
- 最大数字序列和问题,买卖股票问题,以及最长公共字串问题
- 动态规划---实现输出最大公共子序列的长度以及输出最大子字符串(java语言描述)
- HDU 1231 最大连续子序列 &&HDU 1003Max Sum (区间dp问题)
- 分治法对最大连续和以及归并排序,分治与递归实质把问题区间区域分割成几个小区间或者小分区,一直下钻到一个元素小区解决问题
- 每日三题-Day1-C(HDU 1069 Monkey and Banana 最大有序子序列和)
- HDU 1231 最大连续子序列 &&HDU 1003Max Sum (区间dp问题)
- java动态规划 实现输出最大公共子序列的长度以及输出最大子字符串
- 最大子序列分治实现以及改进
- 动态规划_最大子序列和问题以及最大子序列问题
- 每日一题(20) - 最大子序列和
- 动态规划 字符串最大公共子序列以及最大公共子串问题LCS
- UVALive - 3938 Ray, Pass methe dishes!"(动态最大连续和子序列,线段树区间合并)
- 最大子序列和问题以及确定序列起终点位置
- 关于最大子序列和问题以及相关衍生问题的分析
- HDU-#1003 Max Sum(DP+区间最大子序列)