Acwing.1087修剪草坪

文章介绍了如何解决一个优化问题,即在不能选择连续的m只奶牛工作的情况下,求解最大工作效率。通过状态表示f[i]来表示从第1头到第i头奶牛工作的最大效率,利用状态转移和单调队列优化,找到在前m头奶牛中使效率最大的策略。此外,还提到了烽火传递的另一种解题方法。
摘要由CSDN通过智能技术生成

 

 题意:不能挑选连续的m只奶牛去工作,求最大效率。

状态表示:f[i]表示从第1头奶牛开始到第i头奶牛合理工作的最大效率。

状态转移:1、第i头奶牛不工作,那么效率就是f[i - 1]

                  2、第i头奶牛工作,那么在第[i - m , i - 1]中必须有一头奶牛不工作, 假设第j头牛不工作那么效率为 :第j + 1头牛到第i头牛的效率和加上f[j - 1];利用前缀和求解第j + 1头牛到第i头牛的效率和。即f[i] = max{f[j - 1] + S[i] - S[i - j]},(i - m <= j <= i - 1),由于i为固定值,因此即为f[i] = max{f[j - 1] - S[i - j]} + S[i],只需用单调队列维护在i的前m个奶牛中,f[j - 1] - S[i - j]的最大值即可。 

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long ll;

const int N = 100010;

int n, m;
ll s[N];
ll f[N];
int q[N];

ll g(int i)
{
    return f[i - 1] - s[i];
}

int main(void)
{
    scanf("%d%d" ,&n, &m);
    for(int i = 1; i <= n; i ++)
    {
        scanf("%d", &s[i]);
        s[i] += s[i - 1];
    }
    int hh = 0, tt = 0;
    for(int i = 1; i <= n; i ++)
    {
        if(q[hh] < i - m)   hh ++;
        f[i] = max(f[i - 1], g(q[hh]) + s[i]);//先用后维护,与第i头奶牛的信息无关
        while(hh <= tt && g(q[tt]) <= g(i)) tt --;
        q[++ tt] = i;
    }
    printf("%lld\n", f[n]);
    return 0;
}

也可以用烽火传递的方法来做这道题,转化为在连续m头奶牛中必须至少有一头奶牛休息,求出这些奶牛休息的最小效率,最后用效率总和捡起这个最小效率即为答案。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值