CF1358E Are You Fired?(前缀和+贪心)

首先,如果k可以,那么2*k一定可以,因为这是两个k合并而来,因此如果存在答案,那么在n/2+1中一定存在答案

对于x分为两种,当x>=0,那么f[n]是最优的,只需要判断一下他即可

对于x<0我们可以尝试枚举k,首先从最大开始往下,因为k每减小一位,意味着出现了一段前缀和,以及之前的最小值减去x。因此只要不停的枚举后判断最小值是否大于0

减去k的原因是,后面的数字都是x,且我们枚举的长度大于k

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+10;
int a[N];
ll s[N];
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    for(i=1;i<=(n+1)/2;i++)
        cin>>a[i];
    int x;
    cin>>x;
    for(i=(n+1)/2+1;i<=n;i++){
        a[i]=x;
    }
    for(i=1;i<=n;i++)
        s[i]=s[i-1]+a[i];
    if(x>=0){
        if(s[n]>0){
            cout<<n<<endl;
        }
        else{
            cout<<-1<<endl;
        }
    }
    else{
        ll res=1e18;
        for(i=1;i<=(n+1)/2;i++){
            if(i==1){
                res=s[n];
            }
            else{
                res-=x;
                res=min(res,s[n]-s[i-1]);
            }
            if(res>0){
                cout<<n-i+1<<endl;
                return 0;
            }
        }
        cout<<-1<<endl;
    }
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/13527785.html