• Codevs 1648 最大和


    1648 最大和
    时间限制: 1 s
    空间限制: 256000 KB
    题目等级 : 钻石 Diamond
    传送门
    题目描述 Description
    N个数围成一圈,要求从中选择若干个连续的数(注意每个数最多只能选一次)加起来,问能形成的最大的和。
    输入描述 Input Description
    第一行输入N,表示数字的个数,第二行输入这N个数字。
    输出描述 Output Description
    输出最大和。
    样例输入 Sample Input
    8
    2 -4 6 -1 -4 8 -1 3
    样例输出 Sample Output
    14
    数据范围及提示 Data Size & Hint
    数据说明:
    40% 1<=N<=300
    60% 1<=N<=2000
    100% 1<= N<=100000,答案在longint范围内.

    /*
    T. 
    连成环啊连成环.
    赶脚数据中负数应该不少.
    所以复杂度在o(n^2/2)~o(n^2)之间.
    然后10^10 华丽丽的T了.
    10^5范围应该考虑logn,log^2n,nlogn…… 
    */
    #include<iostream>
    #include<cstdio>
    #define MAXN 100001*2
    #define LL long long
    using namespace std;
    LL f[MAXN],n,x,s[MAXN],tot=-1e18;
    LL read()
    {
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)  x=read(),s[i]=s[i+n]=x;
        for(int i=1;i<=n;i++){
            if(s[i]>0)
            {
                f[i]=s[i];tot=max(tot,f[i]);
                for(int j=i+1;j<i+n;j++){
                  if(f[j-1]>0) f[j]=f[j-1]+s[j];
                  else f[j]=x;
                tot=max(tot,f[j]);
                }
            }
            tot=max(s[i],tot);
        }
        printf("%lld",tot);
        return 0;
    }
    /*
    一开始怎么也没想到orz.
    其实还是挺好想的.
    答案的贡献来自于
    (1)连续和(不跨环).
    (2)连续和(跨环).
    不跨环的o(n)扫一遍即可.
    跨环的因为所有数的价值和是一定的
    只需求出最小连续和用价值总和减掉即可(显然).
    最后两者取大. 
    */
    #include<iostream>
    #include<cstdio>
    #define LL long long
    #define MAXN 100001
    using namespace std;
    LL x,tot1,tot2,tot,n,ans1=-1e12,ans2=1e12;
    LL read()
    {
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    int main()
    {
        n=read();x=read();
        tot=tot1=tot2=x;
        for(int i=2;i<=n;i++)
        {
            x=read();
            if(tot1>0) tot1+=x;
            else tot1=x;
            if(tot2<0) tot2+=x;
            else tot2=x;
            tot+=x;
            ans1=max(ans1,tot1),ans2=min(ans2,tot2);
        }
        printf("%lld",max(tot-ans2,ans1));
        return 0;
    }
  • 相关阅读:
    【spring mvc】application context中【bean】的生命周期
    【spring mvc】基础概念
    TSql Work with comma
    统计公司人数
    t_sql中的COUNT函数
    T_SQL又另外两种找出3年连续获奖的人
    A Sql Stumper
    验证ISIN, SEDOLE和CUSIP
    按月份进行统计
    使用4中不同的方式找出连续三年获奖的人
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070804.html
Copyright © 2020-2023  润新知