CodeForces - 961B:Lecture Sleep(前缀和)

39 篇文章 1 订阅

链接https://vjudge.net/problem/CodeForces-961B

题目
Your friend Mishka and you attend a calculus lecture. Lecture lasts n minutes. Lecturer tells ai theorems during the i-th minute.

Mishka is really interested in calculus, though it is so hard to stay awake for all the time of lecture. You are given an array t of Mishka’s behavior. If Mishka is asleep during the i-th minute of the lecture then ti will be equal to 0, otherwise it will be equal to 1. When Mishka is awake he writes down all the theorems he is being told — ai during the i-th minute. Otherwise he writes nothing.

You know some secret technique to keep Mishka awake for k minutes straight. However you can use it only once. You can start using it at the beginning of any minute between 1 and n - k + 1. If you use it on some minute i then Mishka will be awake during minutes j such that and will write down all the theorems lecturer tells.

You task is to calculate the maximum number of theorems Mishka will be able to write down if you use your technique only once to wake him up.

题意
现在正在上课,时长n分钟。老师每分钟会讲ai个知识点。
即使小M很想要学习,但他还是忍不住在某几分钟的时候会打个盹(这才是好学生,respect!)。
作为小M的好朋友,你可以在任何时间叫醒他。
被叫醒的小M会获得debuff“激发的斗志”,小M接下来k分钟之内不再会睡觉,努力学习。

问:小M在你的帮助下这节课最多能够学到多少知识点?

思路
求前缀和就好。

首先我们先把状态为1对应的知识点数量加起来,这是小M一定会获得的。
接下来我们对状态为0对应的知识点求前缀和:
(其实就是把小M在每分钟遗漏的总知识点数全部求出来)

for(int i=1; i<=n; i++)
    cin>>v[i];          //第i分钟的知识点数
for(int i=1; i<=n; i++)
{
    cin>>w[i];          //对应小M状态
    if(w[i])
        sum+=v[i];
}
memset(pre,0,sizeof(pre));
for(int i=1; i<=n; i++)
{
    if(w[i])
        pre[i]=pre[i-1];  //如果当前小M是醒着的,不用管
    else
        pre[i]=pre[i-1]+v[i];  //睡着了就是之前遗漏的加上当前的
}

接下来我们就看在区间长度为k的区间里,哪个区间漏的多,找到这个区间的开始时间,然后在这个时候把小M叫醒就好。

看代码吧,伊丽莎白!

在这里插入图片描述
代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
int v[maxn],w[maxn],pre[maxn];
int main()
{
    int sum=0,maxt=0;
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=n; i++)
        cin>>v[i];
    for(int i=1; i<=n; i++)
    {
        cin>>w[i];
        if(w[i])
            sum+=v[i];
    }
    memset(pre,0,sizeof(pre));
    for(int i=1; i<=n; i++)
    {
        if(w[i])
            pre[i]=pre[i-1];
        else
            pre[i]=pre[i-1]+v[i];
    }
    for(int i=1; i<=n; i++)
    {
        maxt=max(maxt,pre[i+m-1]-pre[i-1]);   //注意这里的区间
    }
    cout<<sum+maxt<<endl;
}

又是充实(lao lei)的一天,下次再见~~

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值