码迷,mamicode.com
首页 > 编程语言 > 详细

[51NOD1959]循环数组最大子段和(dp,思路)

时间:2016-10-24 20:55:05      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:using   for   sum   序列   最大子段和   name   htm   ace   .com   

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050

这道题的最大子段和有两种可能,一种是常规的子段和,另一种是从结尾到开头的一个子段。常规做是一种可能,另一种带循环的则可以认为是序列中间有一段最小子段和,把这段最小子段和去掉,剩下的可能就是最大子段和了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 50050 * 2;
 6 int n;
 7 int a[maxn];
 8 
 9 int main() {
10   // freopen("in", "r", stdin);
11   while(~scanf("%d", &n)) {
12     bool flag = 0;
13     LL sum = 0, ret1 = 0, ret2 = 0;
14     for(int i = 1; i <= n; i++) {
15       scanf("%d", &a[i]);
16       sum += a[i];
17       if(a[i] < 0) flag = 1;
18     }
19     if(!flag) {
20       printf("%lld\n", sum);
21       continue;
22     }
23     LL tmp = 0;
24     for(int i = 1; i <= n; i++) {
25       ret1 = max(tmp, ret1);
26       tmp += a[i];
27       if(tmp < 0) tmp = 0;
28     }
29     for(int i = 1; i <= n; i++) a[i] = -a[i];
30     tmp = 0;
31     for(int i = 1; i <= n; i++) {
32       ret2 = max(tmp, ret2);
33       tmp += a[i];
34       if(tmp < 0) tmp = 0;
35     }
36     printf("%lld\n", max(ret1, sum+ret2));
37   }
38   return 0;
39 }

 

[51NOD1959]循环数组最大子段和(dp,思路)

标签:using   for   sum   序列   最大子段和   name   htm   ace   .com   

原文地址:http://www.cnblogs.com/kirai/p/5994215.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!