每日一题(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;}
- 每日一题(50) - 绝对值最大的子序列和以及其区间
- 每日一题(51) - 最大子序列积以及区间
- 每日一题(20) - 最大子序列和
- 每日一题(81) - 子数组之和的最大值(二维) - 最大子矩阵和
- 每日一练-----最大连续子数组的和
- 最大子段和绝对值
- 每日一题(77) - 子数组的最大乘积
- <每日一题>最大回文子字符串
- 最大子序列的和
- 和最大的子序列
- 子序列的最大和
- 子序列的最大和
- 【最大子序列的和】
- 最大子序列的和
- 最大子区间和
- 每日三题-Day1-C(HDU 1069 Monkey and Banana 最大有序子序列和)
- 数据结构一:最大子序列和问题
- 每日一题(28) - 找出绝对值最小的元素
- Oracle解锁
- SharePoint 2010 Server Error: The URL "XXX" is invalid, it may refer to a nonexistent file or ...
- hdu3466(01背包)
- python多线程并发执行程序实战讲解
- typeof
- 每日一题(50) - 绝对值最大的子序列和以及其区间
- libtool: link: `ext/standard/info.lo' is not a valid libtool object
- 最近开发Android的一些总结
- HDU 1002 A + B Problem II
- 戴维南定理
- svn co 默认密钥' GNOME keyring
- MYSQLMANAGER实例管理器总结
- 浅议柔性数组
- UNIX网络编程——套接字选项(setsockopt)