列表

详情


NC50530. 修剪草坪

描述

在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪。现在,新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠。
然而,FJ的草坪非常脏乱,因此,FJ只能够让他的奶牛来完成这项工作。FJ有N只排成一排的奶牛,编号为1到N。每只奶牛的效率是不同的,奶牛i的效率为E_i
靠近的奶牛们很熟悉,如果FJ安排超过K只连续的奶牛,那么这些奶牛就会罢工去开派对。因此,现在FJ需要你的帮助,计算FJ可以得到的最大效率,并且该方案中没有连续的超过K只奶牛。

输入描述

第一行:空格隔开的两个整数N和K;
第二到N+1行:第i+1行有一个整数E_i

输出描述

一行一个值,表示FJ可以得到的最大的效率值。

示例1

输入:

5 2
1
2
3
4
5

输出:

12

说明:

FJ有5只奶牛,他们的效率为1,2,3,4,5。他们希望选取效率总和最大的奶牛,但是他不能选取超过2只连续的奶牛。FJ选择出了第三只以外的其他奶牛,总的效率为1+2+4+5=12。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 25ms, 内存消耗: 3492K, 提交时间: 2023-03-17 17:00:24

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,k;
int a[N],f[N],sum[N],d[N],q[N];
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>k;
    int head=1,tail=1;
    for(int i=1;i<=n;++i){
        cin>>a[i];
        sum[i]=sum[i-1]+a[i];
        d[i]=f[i-1]-sum[i];
        while(head<=tail&&d[q[tail]]<d[i]) tail--;
        q[++tail]=i;
        while(head<=tail&&i-k>q[head]) head++;
        f[i]=sum[i]+d[q[head]];
    }
    cout<<f[n];
    
    return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 45ms, 内存消耗: 1924K, 提交时间: 2023-03-29 21:34:28

#include<iostream>
using namespace std;
const int N=1e5+10;
#define ll long long
ll s[N],q[N],dp[N];
ll g(ll x)
{
    return dp[x-1]-s[x];
}
int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        cin>>s[i],s[i]+=s[i-1];
    int h=0,t=0;
    for(int i=1;i<=n;i++)
    {
        if(q[h]<i-k)h++;
        dp[i]=max(dp[i-1],g(q[h])+s[i]);
        while(h<=t&&g(q[t])<g(i))t--;
        q[++t]=i;
    }
    cout<<dp[n];
    return 0;
}

上一题