2019 蓝桥杯省赛 B 组模拟赛(一) J. 程序设计:蒜厂年会 环形连续子序列求和问题

在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 nnn 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币。但是这个游戏比较坑,里面竟然有负数,表示你要支付多少蒜币。因为这些数字都是可见的,所以大家都是不会出现的赔的情况。

游戏规则:每人只能抓一次,只能抓取一段连续的纸团,所有纸团上的数字和就是你可以获得的蒜币。

蒜头君作为蒜厂的一员在想,我怎么可以获得最多的蒜币呢?最多能获取多少蒜币呢?

因为年会是发奖,那么一定有大于 000 的纸团。

输入格式

第一行输入一个整数 nnn,表示有 nnn 个纸团。

第二行输入输入 nnn 个整数 aia_iai​,表示每个纸团上面写的数字(这些纸团的输入顺序就是环形桌上纸团的摆放顺序)。

输出格式

输出一个整数,表示蒜头君最多能获取多少蒜币。

数据范围

对于 30%30\%30% 的数据:1≤n≤102,−103≤ai≤1031 \le n \le 10^2,-10^3 \le a_i \le 10^31≤n≤102,−103≤ai​≤103。

对于 60%60\%60% 的数据:1≤n≤5×103,−106≤ai≤1061 \le n \le 5 \times 10^3,-10^6 \le a_i \le 10^61≤n≤5×103,−106≤ai​≤106。

对于 100%100\%100% 的数据:1≤n≤105,−109≤ai≤1091 \le n \le 10^5,-10^9 \le a_i \le 10^91≤n≤105,−109≤ai​≤109。

样例输入

3
1 -2 1

样例输出

2

思路:

分别求出最大连续子序列和maxsum和最小连续子序列和minsum,然后输出maxsum和sum-minsum中最大值即可。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n;
int a[maxn];
ll sum=0;
int main()
{
    scanf("%d",&n);
    for (int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    ll minsum=a[0],maxsum=a[0];
    ll mintemp=0,maxtemp=0;
    for (int i=0;i<=n;i++)
    {
        mintemp+=a[i];
        maxtemp+=a[i];
        minsum=min(minsum,mintemp);
        maxsum=max(maxsum,maxtemp);
        if(maxtemp<0) maxtemp=0;
        if(mintemp>0) mintemp=0;
    }
    printf("%lld\n",max(maxsum,sum-minsum));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41410799/article/details/87436835