ayit 蚂蚁的难题

来源:互联网 发布:中小学预算编制软件 编辑:程序博客网 时间:2024/05/17 03:23

http://ayit.acmclub.com/index.php?app=problem_title&id=233&problem_id=21816

最大字段和的变形,圆环的最大字段和有两种可能。1、如果最大字段和包含开头和结尾,那么最小字段和一定被最大字段和包围在最中间。2、如果最大字段和不同时包含开头和结尾,只需求出最大字段和即可。

求出以上两种情况的最小字段和   和   最大字段和。然后用总和 减去最小字段和   和   最大字段和进行比较即可,找到较大的值即可。

#include<stdio.h>#include<iostream>#include<string.h>#include<limits.h>using namespace std;long long maxx(long long a,long long b,long long c ){    a = a>b?a:b;    a = a>c?a:c;    return a;}long long minn(long long a,long long b,long long c){    a = a<b?a:b;    a = a<c?a:c;    return a;}long long dfs_max(int a[],int left,int right){    long long i,m,lmax,rmax,sum;    if(left == right) return a[left];    m = (left + right)/2;    lmax = sum = 0;    for(i = m; i >= left; i--)    {        sum += a[i];        lmax = lmax>sum?lmax:sum;    }    rmax = sum = 0;    for(i = m+1; i <= right;i++)    {        sum += a[i];        rmax = rmax>sum?rmax:sum;    }    return maxx(lmax+rmax,dfs_max(a,left,m),dfs_max(a,m+1,right));}long long dfs_min(int a[],int left,int right){    long long i,m,lmin,rmin,sum;    if(left == right) return a[left];    m = (left + right)/2;    lmin = 0;    sum = 0;    for(i = m; i >= left; i--)    {        sum += a[i];        lmin = lmin<sum?lmin:sum;    }    rmin = 0;    sum = 0;    for(i = m+1; i <= right;i++)    {        sum += a[i];        rmin = rmin<sum?rmin:sum;    }    return minn(lmin+rmin,dfs_min(a,left,m),dfs_min(a,m+1,right));}int main(){    int N,n,a[50010];    long long sum;    while(scanf("%d",&n) != EOF)    {        sum = 0;        memset(a,0,sizeof(a));        for(int i = 0; i < n; i++)        {            scanf("%d",&a[i]);            sum+= a[i];        }        long long max0 = dfs_max(a,0,n-1);        long long min0 = dfs_min(a,0,n-1);        printf("%lld\n",(sum - min0)>max0?(sum - min0):max0);    }    return 0;}


0 0
原创粉丝点击