poj2479 Maximum sum

http://poj.org/problem?id=2479

 

题目大意:给定一组n个整数:a ={a1, a2,…,我们定义一个函数d(a)如下:

 

你的任务是计算d(A)。输入由T(<=30)测试用例组成。在输入的第一行中给出了测试用例(T)的数量。

每个测试用例包含两行。第一行是一个整数n(2<=n<=50000)。第二行包含n个整数:a1, a2,…,an。 ( | ai |  < = 10000)。为每个测试用例打印一行。该行应该包含整数d(A)。

 

也就是说求最大的子段和,给定一个数组,求数组里左子段的和加上右子段的和的最大值。

 

算法思想:动态规划,用left[i]表示第1个数到第i个数的最大子段和,用right[i]表示第i个数到第n个数的最大值。我们要求的就是left[i]+right[i+1]的最大值。

状态转移方程:

1) left[i]=max{left[i-1]+a[i],a[i]}  i=1,2,3,…;

2) right[i]=max{right[i+1]+a[i],a[i]}   i=n,n-1,…;

3) max=max{left[i]+right[i+1]}   i=n,n-1,…;

 1 #include <iostream>
 2 using namespace std;
 3 int MaximumSum(int a[],int n)
 4 {
 5     int sum = 0, max=INT_MIN;
 6     int *left, *right;
 7     left = new int[n + 1];
 8     right = new int[n + 2];
 9     left[0] = -10001;
10     right[n + 1] = -10001;
11     for (int i = 1; i < n; i++)
12     {
13         sum = sum + a[i];
14         if (sum > left[i-1])left[i] = sum;
15         else left[i] = left[i-1];
16         if (sum < 0)sum = 0;//累加为负数时更新sum
17     }
18     sum = 0;
19     for (int i = n; i > 1; i--)
20     {
21         sum = sum + a[i];
22         if (sum > right[n+1])right[i] = sum;
23         else right[i] = right[i + 1];
24         if (sum < 0)sum = 0;
25         if (right[i] + left[i - 1] > max)max = right[i] + left[i - 1];//在此可直接计算max
26     }
27     delete []left;
28     delete []right;
29     return max;
30 }
31 int main()
32 {
33     int t, n;
34     int array[50001];
35     cin >> t;
36     for (int i = 0; i < t; i++)
37     {
38         cin >> n;
39         for (int j = 1; j <= n; j++)
40         {
41             scanf_s("%d", &array[j]);
42         }
43         cout << MaximumSum(array, n) << endl;
44     }
45 
46     return 0;
47 }

 

posted @ 2018-05-05 16:23  Angel_Q  阅读(306)  评论(0编辑  收藏  举报