筷子与饺子
Published on 2019-11-11 04:08 in 暂未分类 with 筷子与饺子

最大序列和

题目描述

给出一个整数序列S,其中有N个数,定义其中一个非空连续子序列T中所有数的和为T的“序列和”。 对于S的所有非空连续子序列T,求最大的序列和。 变量条件:N为正整数,N≤1000000,结果序列和在范围(-2^63,2^63-1)以内。

输入描述:

第一行为一个正整数N,第二行为N个整数,表示序列中的数。

输出描述:

输入可能包括多组数据,对于每一组输入数据,
仅输出一个数,表示最大序列和。
示例1

输入

5
1 5 -3 2 4

6
1 -2 3 4 -10 6

4
-3 -1 -2 -5

输出

9
7
-1

解题思路

1、该题的思路有很多种,首先看最简单的遍历求解。

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int N;
 5     while(scanf("%d",&N)!=EOF)
 6     {
 7         int a[N];
 8         int sum = 0;
 9         for(int i=0;i<N;i++)
10             scanf("%d",&a[i]);
11         for(int i = 0;i<N;i++)
12         {
13             int thissum = 0;
14             for(int j = i;j<N;j++)
15             {
16                  thissum+=a[j];
17                 if(thissum >sum)
18                 {
19                     sum = thissum;
20                 }
21             } 
22         }
23         printf("%d",sum);
24     }
25 }

分析:由代码可知,此算法显然需要O(n2)的复杂度,部分样例会超出时间限制。

2、最大序列和的动态规划算法

设b[j] 为从第 i 到第 j 个数字的最大序列和

即  b[j] = max1<=i<=j {SUM k= i -- j a[k] }

由 b[j] 的定义可知,当b[j-1]>0 时,b[j] = b[j-1]+a[j], 否则b[j] = a[j]。

所以得出动态规划递归式:

b[j] = max {b[j-1]+a[j] , a[j]} 1<=j<=n

由此得出求最大序列和的动态规划算法如下:

换一个编译环境编写:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int n;
 8     while(cin >> n)
 9     {
10         int a[n];
11         for(int i = 0;i<n;i++)
12         {
13             cin >> a[i];
14         }
15         int sum =0,b = 0;
16         for(int i = 0;i<n;i++)
17         {
18             if(b>0) b = b+ a[i];
19             else b = a[i];
20             if(b>sum) sum = b;
21         }
22         printf("%d",sum);
23     }
24 }

上述算法所需要的O(n) 的计算时间。

posted @ 2019-08-17 17:10  筷子与饺子  阅读(236)  评论(0编辑  收藏  举报