每日一题(50) - 绝对值最大的子序列和以及其区间

来源:互联网 发布:中国男人非洲女人 知乎 编辑:程序博客网 时间:2024/05/14 22:03

题目来自网络

题目:给定数组,求其 绝对值最大的子序列和以及对应的区间

举例:数组{-5,4,-20,16,-2,-3}的绝对值最大的子序列和为-21,其区间为[0,2]

思路:可以使用动态规划求解

由于求解的是绝对值最大,需要考虑负值。结果可以转化为要么是和最大(正数),要么是和最小(负数)。

可以使用两个数组保存以第i个数为止的子序列之和的最大值和最小值,之后可以根据这个最大值和最小值往i+ 1个数进行扩展。

对比:对于求解最大子序列和的问题,其实其一个子问题,只需要使用一个数组保存其最大值就ok。

注意:这里使用一维数组保存状态,也可以直接使用两个变量保存状态,思路是一样的,代码略。

代码:单纯求解绝对值最大

#include <iostream>#include <assert.h>using namespace std;//Max[i] = max(nArr[i],nArr[i] + Max[i - 1])//Min[i] = min(nArr[i],nArr[i] + min[i - 1]); //初始化//Max[0] = nArr[0]//Min[0] = nArr[0]int AbsMaxSubSum(int arr[],int nLen){int Max[100];int Min[100];int nAbsMaxSubSum;Max[0] = arr[0];Min[0] = arr[0];nAbsMaxSubSum = arr[0];for (int i = 1;i < nLen;i++){Max[i] = max(Max[i - 1] + arr[i],arr[i]);Min[i] = min(Min[i - 1] + arr[i],arr[i]);if (abs(Max[i]) > abs(nAbsMaxSubSum)){nAbsMaxSubSum = Max[i];}if (abs(Min[i]) > abs(nAbsMaxSubSum)){nAbsMaxSubSum = Min[i];}}return nAbsMaxSubSum;}int main(){int arr[8] = {4,-3,5,-2,-1,2,6,-2};int nLen = 8;cout<<AbsMaxSubSum(arr,nLen)<<endl;int arr1[1] = {-5};int nLen1 = 1;cout<<AbsMaxSubSum(arr1,nLen1)<<endl;int arr2[2] = {0,-5};int nLen2 = 2;cout<<AbsMaxSubSum(arr2,nLen2)<<endl;int arr3[6] = {-5,4,-20,16,-2,-3};int nLen3 = 6;cout<<AbsMaxSubSum(arr3,nLen3)<<endl;int arr4[2] = {-5,0};int nLen4 = 2;cout<<AbsMaxSubSum(arr4,nLen4)<<endl;int arr5[4] = {-5,0,-3,2};int nLen5 = 4;cout<<AbsMaxSubSum(arr5,nLen5)<<endl;system("pause");return 1;}

代码:求最大值和区间

#include <iostream>#include <assert.h>using namespace std;//Max[i] = max(nArr[i],nArr[i] + Max[i - 1])//Min[i] = min(nArr[i],nArr[i] + min[i - 1]); //初始化//Max[0] = nArr[0]//Min[0] = nArr[0]int AbsMaxSubSum(int arr[],int nLen){int Max[100];int Min[100];int nAbsMaxSubSum = arr[0];int nCurMaxStart = 0;int nCurMinStart = 0;int nMaxStart = 0;int nMaxEnd = 0;Max[0] = arr[0];Min[0] = arr[0];for (int i = 1;i < nLen;i++){if (Max[i - 1] + arr[i] > arr[i]){Max[i] = Max[i - 1] + arr[i];}else{Max[i] = arr[i];nCurMaxStart = i;}if (Min[i - 1] + arr[i] < arr[i]){Min[i] = Min[i - 1] + arr[i];}else{Min[i] = arr[i];nCurMinStart = i;}if (abs(Max[i]) > abs(nAbsMaxSubSum)){nAbsMaxSubSum = Max[i];nMaxEnd = i;nMaxStart = nCurMaxStart;}if (abs(Min[i]) > abs(nAbsMaxSubSum)){nAbsMaxSubSum = Min[i];nMaxEnd = i;nMaxStart = nCurMinStart;}}cout<<"区间: "<<nMaxStart<<" - "<<nMaxEnd<<endl;return nAbsMaxSubSum;}int main(){int arr[8] = {4,-3,5,-2,-1,2,6,-2};int nLen = 8;cout<<AbsMaxSubSum(arr,nLen)<<endl;int arr1[1] = {-5};int nLen1 = 1;cout<<AbsMaxSubSum(arr1,nLen1)<<endl;int arr2[2] = {0,-5};int nLen2 = 2;cout<<AbsMaxSubSum(arr2,nLen2)<<endl;int arr3[6] = {-5,4,-20,16,-2,-3};int nLen3 = 6;cout<<AbsMaxSubSum(arr3,nLen3)<<endl;int arr4[2] = {-5,0};int nLen4 = 2;cout<<AbsMaxSubSum(arr4,nLen4)<<endl;int arr5[4] = {-5,0,-3,2};int nLen5 = 4;cout<<AbsMaxSubSum(arr5,nLen5)<<endl;system("pause");return 1;}


原创粉丝点击