首页 > 技术文章 > NOI Online #3 提高组 T1水壶 题解

liuchanglc 2020-05-24 14:43 原文

题目描述

\(n\) 个容量无穷大的水壶,它们从 \(1\sim n\) 编号,初始时 \(i\) 号水壶中装有 \(A_i\) 单位的水。

你可以进行不超过 \(k\) 次操作,每次操作需要选择一个满足 \(1≤x≤n−1\) 的编号 \(x\),然后把 \(x\) 号水壶中的水全部倒入 \(x+1\) 号水壶中。

最后你可以任意选择恰好一个水壶,并喝掉水壶中所有的水。现在请你求出,你最多能喝到多少单位的水。

输入格式

第一行一个正整数 \(n\),表示水壶的个数。

​第二行一个非负整数 \(k\),表示操作次数上限。

​第三行 \(n\) 个非负整数,相邻两个数用空格隔开,表示水壶的初始装水量 \(A_1、A_2 \cdots An\)

输出格式

一行,仅一个非负整数,表示答案。

输入输出样例

输入 #1

10
5
890 965 256 419 296 987 45 676 976 742

输出 #1

3813

分析

这道题比之前的 \(T1\) 友好多了

首先,倒水的这几个水壶肯定要相连,否则不会产生最大的价值

那么我们就可以把问题转化为在一个序列中求一段长度固定的区间的和,使这个和最大

这样的话我们用前缀和记录一下就好了,复杂度为 \(O(n)\)

这道题唯一需要注意的是倒 \(k\) 次水,区间的长度为 \(k+1\)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn=1e6+5;
ll a[maxn],qzh[maxn];
int main(){
    ll n,k;
    scanf("%lld%lld",&n,&k);

    for(ll i=1;i<=n;i++){
        scanf("%lld",&a[i]);

        qzh[i]=a[i]+qzh[i-1];
    }
    k++;
    ll ans=-1;
    for(ll l=1;l<=n;l++){
        ll r=l+k-1;
        if(r>n) break;

        ans=max(ans,qzh[r]-qzh[l-1]);
    }
    printf("%lld\n",ans);
    return 0;
}

推荐阅读