环状最大连续和

(最大连续和)

小学生一发

一道环状的最大连续和。

蒜厂年会

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

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

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

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

输入:
第一行输入一个整数 n n ,表示有 n n 个纸团。 ( n 1 0 5 ) (n\leq 10^5)
第二行输入 n n 个整数 a i a_i , 表示每个纸团上面写的数字
(这些纸团的输入顺序就是环形桌子上纸团的摆放顺序)。 ( 1 0 9 a i 1 0 9 ) (-10^9 \leq a_i\leq 10^9)

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

解析

本题是最大连续和的一个变形,把序列变成环形了而已。怎么求呢,首先肯定要先求出序列的最大连续和,这个直接分治法或者 d p dp 一下就完事了。考虑到最大值可能存在首尾相接上,这样我们就需要引入数组 s u m sum , s u m i sum_i 表示从 1 1 i i 的前缀和中的最大值,这样就只需要统计后缀和,再加上前缀和的最大值就行。

AC代码:

//  小学生一发的刷题之路
//  最大连续和-环状
//  dp,前缀和;
//
//


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <deque>                //双向队列;
#include <cmath>
#include <set>
#include <stack>
#include <map>
#include <vector>
#include <cstdlib>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const double PI=acos(-1.0);
const double eps=1e-8;
const double e=exp(1.0);
const int maxn=1e5+5;
const int maxm=1e6+5;
const ll mod=1e9+7;
const int INF=1e8;
template<class T>
void read(T &ret){              //快速输入模版;
    ret=0;
    int f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        ret=ret*10+c-'0';
        c=getchar();
    }
    ret*=f;
}
int n;
ll a[maxn],dp[maxn],sum[maxn];

int main()
{
    memset(sum,0,sizeof(sum));
    scanf("%d",&n);
    ll ans1=0,tmp=0,maxa=0;
    dp[0]=0,sum[0]=0;
    for(int i=1;i<=n;i++){
        read(a[i]);
        tmp+=a[i];
        maxa=max(maxa,tmp);
        sum[i]=maxa;
        if(dp[i-1]>0){
            dp[i]=dp[i-1]+a[i];
        }else{
            dp[i]=a[i];
        }
        ans1=max(ans1,dp[i]);
    }
    
    ll ans2=0,max_tmp=0;
    tmp=0;
    for(int i=n;i>=1;i--){
        tmp+=a[i];
        max_tmp=max(max_tmp,tmp);
        ans2=max(ans2,sum[i-1]+max_tmp);
    }
    printf("%lld\n",max(ans1,ans2));
    return 0;
}

新的开始,每天都要快乐哈。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_39393640/article/details/87292907
今日推荐