【hpuoj】循环数组最大子段和

来源:互联网 发布:淘宝亚瑟士全是假的 编辑:程序博客网 时间:2024/06/05 20:06

1082: 循环数组最大子段和 [DP]

时间限制: 1 Sec 内存限制: 128 MB

提交: 19 解决: 6 状态

题目描述

KACA在做了最大子段和问题之后,思考若数组可以首尾相接的话最大子段和应该是多少。

输入

有多组测试数据。

每一组的第一行是一个整数nn

下面一行是nn个以空格分开的整数aiai

1N100001≤N≤10000

0|ai|1060≤|ai|≤106

输出

对于每一组数据,输出当数组可以首位相接时的最大子段和,占一行。

样例输入

6-1 4 -1 -5 5 1

样例输出

9

来源

BoilTask

提交论坛

一个经典的入门DP;51Nod算法课程里的模板题;

这道题跟最大连续子段和有区别在这里涉及了循环数组,那么考虑一下其实这题求的是数组中的最小连续子段和。

然后sum减去最小连续子段和就是循环数组的最大连续子段和。

思路早就有了不过不知道为啥一直不过……

#include<cstdio> #include<algorithm>#include<string.h>using namespace std;int n;typedef long long ll;ll a[50010];int main(){    while(~scanf("%d",&n)){        ll sum=0;        for(int i=1;i<=n;i++){            scanf("%lld",&a[i]);            sum+=a[i];        }        ll su=0;        ll su1=0;        ll ma=0;        ll ma1=0;        for(int i=1;i<=n;i++){            if(su<=0){                su=a[i];                if(su>ma){                    ma=su;                }            }            else{                su+=a[i];                if(su>ma){                    ma=su;                }            }            if(su1<=0){                su1=-a[i];                if(su1>ma1){                    ma1=su1;                }             }            else{                su1+=(-a[i]);                if(su1>ma1){                    ma1=su1;                }            }        }        printf("%lld\n",max(ma,sum-(-ma1)));      }    return 0;}


0 0
原创粉丝点击