51Nod 1050 循环数组最大子段和 | DP
Posted kimsimple
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod 1050 循环数组最大子段和 | DP相关的知识,希望对你有一定的参考价值。
Input示例
6 -2 11 -4 13 -5 -2
Output示例
20
分析:
有两种可能,第一种为正常从[1 - n]序列中的最大子字段和;第二种为数组的total_sum - ([1-n]序列中的最短序列和)
最后结果为 max { 第一种, 第二种}。
对于第二种:
循环数组求最大子段和,可能出现中间的一部分不要,要两边的数。比如:-1 4 -1 -5 5 -2 1 -1 3,他的最大子段和就为 左边的-1 4加上右边的5 -2 1 -1 3,也就是,去掉1 -5这一段后的结果。而-1 -5这一段其实是最小字段和(序列总和一定,总和 - 最大子段和 = 最小子段和)
#include "iostream" #include "cstdio" using namespace std; #define LL long long #define N 50010 int arr[N]; int main(){ int n; LL sum,sum01,sum02; while(~scanf("%d",&n)){ sum=0;sum01=0;sum02=0; for(int i=0;i<n;i++){ scanf("%d",&arr[i]); sum+=arr[i]; } LL ans=0; for(int i=0;i<n;i++){ sum01+=arr[i]; sum02-=arr[i]; if(sum01<0)sum01=0; if(sum02<0)sum02=0; ans=max(ans,sum01); ans=max(ans,sum+sum02); } printf("%lld\\n",ans); } return 0; }
以上是关于51Nod 1050 循环数组最大子段和 | DP的主要内容,如果未能解决你的问题,请参考以下文章