您的位置:首页 > 其它

POJ 2479 Maximum sum 动态规划 最大子段和 最大子段积

2018-03-01 16:44 519 查看
http://poj.org/problem?id=2479

题意:在给出的数列中找到不相交的两个子段和,使和最大。分析:对每个i求出[0~i-1]的最大子段和以及[i~n-1]的最大子段和,再相加求最大值。在输入时,进行一次dp,求出从左到右的最大和,保存在dp[i]中(其中求和时sum若小于0则前面的数不用再计算,置0)。然后再从右向左进行一次dp,并不断将ans与sum+dp[i-1]比较取最大值。#include<iostream>
#include<cmath>
using namespace std;
const int Min = -999999999;
int a[50005], dp[50005];
int main()
{
int T, n, sum, MAX, ans;
cin >> T;
while (T--)
{
cin >> n;
sum = 0; MAX = Min;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
sum += a[i];
if (sum > MAX)
MAX = sum;
dp[i] = MAX;//[1,i]最大子段和

if (sum < 0) sum = 0;
}
ans = MAX = Min; sum = 0;
for (int i = n; i > 1; i--)
{
sum += a[i];
if (sum > MAX)
MAX = sum;//i~n最大子段和
if (ans < MAX + dp[i - 1])
ans = MAX + dp[i - 1];
if (sum < 0) sum = 0;
}
cout << ans << endl;
}
return 0;
}
最大子段积:考虑存在负数的情况(负负得正),需要分别记录当前最大正数和最小负数
int maxProduct(vector<int>& nums)
{
// write your code here
int posMax = nums[0];
int negMax = nums[0];
int ret = nums[0];
for (int i = 1; i<nums.size(); i++)
{
int tempPosMax = posMax;
int tempNegMax = negMax;
posMax = max(nums[i], max(nums[i] * tempPosMax, nums[i] * tempNegMax));
negMax = min(nums[i], min(nums[i] * tempPosMax, nums[i] * tempNegMax));
ret = max(ret, posMax);
}
if (ret < 0) return -1;
else	return ret;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 动态规划