zoukankan      html  css  js  c++  java
  • 小阳买水果

    链接:https://ac.nowcoder.com/acm/contest/949/D
    来源:牛客网

    水果店里有 n个水果排成一列。店长要求顾客只能买一段连续的水果。
    小阳对每个水果都有一个喜爱程度 aii,最终的满意度为他买到的水果的喜欢程度之和。
    如果和为正(不管是正多少,只要大于 0 即可),他就满意了。
    小阳想知道在他满意的条件下最多能买多少个水果。
    你能帮帮他吗?

    输入描述:

    第一行输入一个正整数 n,表示水果总数。

    第二行输入 n 个整数 ai,表示小阳对每个水果的喜爱程度。

    输出描述:

    一行一个整数表示结果。(如果 1 个水果都买不了,请输出 0)
    示例1

    输入

    复制
    5
    0 0 -7 -6 1

    输出

    复制
    1

    备注:

    1≤n≤2×1e6,∣ai∣≤1e3


    两种做法:
    O(n)
    就是前缀和排个序,
    求一下前缀和,并且记录每个前缀和的位置,然后把 前缀和从小 到大排序,前缀和相同按照位置,从大到小排序。

    区间和等于两个前缀和相减。排序之后前缀和小的在前大的 在后,只需从前 往后遍历一遍,记录最小位置即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e6+5;
    struct node{
        ll a;
        int p;
    }a[maxn];
    bool cmp(node a,node b){
        if(a.a==b.a) return a.p>b.p;
        else return a.a<b.a;
    }
    int main(){
        a[0].a=0,a[0].p=0;
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i].a);
            a[i].a+=a[i-1].a;
            a[i].p=i;
        }
        sort(a,a+n+1,cmp);
        int p=a[0].p;
        int ans=0;
        for(int i=1;i<=n;i++){
            if(a[i].p>p){
                ans=max(ans,a[i].p-p);
            }else{
                p=a[i].p;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    
    

    首先一个数组a记录权值,然后数组sum保存a的前缀和,数组psum表示从后往前的sum 最大值(即max后缀,易知psum是 单调递减 的),然后枚举起点l(1-n),每次循环令r=n,pos,通过 二分 找到 最大的pos使得满足psum[mid]-sum[l-1]>0(满足题意),然后此时的长度就为pos-i+1,每次循环取max即可~

    
    

    dalao原话:利用前缀和的后缀max的单调性,它是单调递减的,sum[i]表示前缀和,pmax[i]表示从i~n中最大的sum[j],i<=j<=n。然后枚举起点i,在[i,n]上二分终点,只要pmax[mid]>sum[i-1]就表示满足条件,继续增加l=mid+1,否则不满足条件令r=mid-1

    
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e6+5;
    const int mod=1e9+7;
    typedef long long ll;
    int n,ans;
    int a[maxn],sum[maxn],psum[maxn];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",a+i);
            sum[i]=sum[i-1]+a[i];
        }
        psum[n]=sum[n];
        for(int i=n-1;i>=1;i--) psum[i]=max(psum[i+1],sum[i]);
        for(int i=1;i<=n;i++){
            int l=i,r=n,pos=0;
            while(l<=r){
                int mid=(l+r)>>1;
                if(psum[mid]>sum[i-1]){
                    l=mid+1;
                    pos=mid;
                }
                else r=mid-1;
            }
            ans=max(pos-i+1,ans);
        }
        cout<<ans<<endl;
    }
    
    
    
     
  • 相关阅读:
    包含中文的js文件在从cdn搞到本地时造成的问题;
    查询杀死进程
    二维码显示在网页上
    二维码生成器和解析器-java
    N个任务,分配给M个人,那么每个人得到的任务数量----总结经验
    js中文转换成拼音
    Grails连接mysql数据库
    Grails框架+Intellij IDEA工具,写了一个对字符串进行转码,包括纯js转成Base64格式
    java冒泡排序
    对文字简单的加密解密
  • 原文地址:https://www.cnblogs.com/lipu123/p/14312902.html
Copyright © 2011-2022 走看看