标签:arr 最大 子段 int 分而治之 middle 区间 left 子列
分治法\(O(n\log{n})\)
按照“分而治之”的思想,将整个数据区间从中间一分为二,这样我们就将求整个区间的最大子列和转换为求小区间的最大子列和。
设区间左端为left,区间右端为right,区间中间为middle。
思考一下,求小区间的子列和一共存在一下三种情况:
- 求左区间的最大子列和:
[left, middle]
- 求右区间的最大子列和:
[middle + 1, right]
- 求从左区间横跨至右区间的最大子列和
代码实现
#include <iostream>
#include <cmath>
using namespace std;
int K;
const int N = 1e7;
int arr[N];
/*从左区间横跨至右区间的情况*/
int getSpecialSum(int left, int right)
{
int middle = (left + right) / 2;
int leftSum = 0, leftSumMax = arr[middle];
int rightSum = 0, rightSumMax = arr[middle + 1];
for (int i = middle; i >= left; i--)
{
leftSum += arr[i];
leftSumMax = max(leftSum, leftSumMax);
}
for (int i = middle + 1; i <= right; i++)
{
rightSum += arr[i];
rightSumMax = max(rightSum, rightSumMax);
}
return leftSumMax + rightSumMax;
}
/*主体*/
int getMaxSum(int left, int right)
{
if (left == right)
return arr[left];
else {
int middle = (left + right) / 2;
int leftSumMax = getMaxSum(left, middle);
int rightSumMax = getMaxSum(middle + 1, right);
int specialSumMax = getSpecialSum(left, right);
return max(max(leftSumMax, rightSumMax), specialSumMax);
}
}
int main()
{
cin >> K;
for (int i = 0; i < K; i++) cin >> arr[i];
cout << getMaxSum(0, K - 1) << endl;
return 0;
}
标签:arr,最大,子段,int,分而治之,middle,区间,left,子列 来源: https://www.cnblogs.com/mightcell/p/16353633.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。