题目是最大子序列和问题,跟以往的不同是和可以是负数,所以只需要改一下求最大子序列和的代码即可,依然是O(n)的时间复杂度
思路是从左向右不断地找出每一个有可能成为最大和的子序列,用submax保存,每一次将它与Max进行比较更新Max
submax的寻找方法是当前面序列a[i] ~a[j] 段的submax为负数时,将前面这段抛弃,另起炉灶,使submax = a[j+1],因为前面的负数部分只会
使submax减小,所以将其抛弃(需要注意的是题目可能有多种情况,找出第一种,所以submax=0时还得保留)
另外编程珠玑上面讲这个问题的几种解决方式讲的很详细,递归虽然要O(n*logn)的复杂度,但觉得还是特别赞的方法
代码如下:
//最大子序列和变形 #include <stdio.h> #include <algorithm> #include <iostream> using namespace std; int main() { int N, T, i, k = 0, a[100010]; int Max, submax; bool flag = 0; cin >> T; while (k++ < T) { cin >> N; if (flag) cout << endl; submax = Max = -100000; //初始化为负无穷 int s, t, s1; for (i = 0; i < N; i++) { cin >> a[i]; //找出子串 if (submax < 0) { s1 = i; submax = a[i]; } else { submax += a[i]; } //更新Max if (submax > Max) { s = s1; t = i; Max = submax; } } cout << "Case " << k << ":" << endl << Max << " " << s+1 << " " << t+1 << endl; flag = 1; } return 0; }