codeforces949D Curfew

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yzyyylx/article/details/88664582

题面

题意

一条直线上有n个寝室,每个寝室中有 a i a_i 个人,现在有两个宿管分别从左右两边向中间走,每个单位的时间查一个寝室,若人数不足b个,则会记录,最中间的寝室归左边的宿管,现在每个人每个单位的时间可以跑d个寝室,则两个宿管记录下的寝室数量的较大值的最小值是多少。

做法

这题有一个很棒的贪心,可以从左向右扫(直到中间),如果可以到达这个寝室的人数(在宿管来之前)大于等于b,就让这些人过来,反之不过来且答案++,然后再倒着做一遍相同的事,两个答案中的较大值即为答案。
可以发现,中间的人向左走似乎会让右边的答案不优,但是可以发现,中间的人向左走的前提是左边的人数不够,也就是右边的人数有多,因此答案不会变劣。

代码

#include<bits/stdc++.h>
#define N 100100
using namespace std;

int n,d,b,num[N],A,B,sum;

int main()
{
    int i,j;
    cin>>n>>d>>b;
    for(i=1;i<=n;i++) scanf("%d",&num[i]);
    for(i=j=1;i<=(n+1)/2;i++)
    {
		for(;j<=min(i*(d+1),n);j++) sum+=num[j];
		if(sum<b) A++;
		else sum-=b;
    }
    reverse(num+1,num+n+1);
    sum=0;
    for(i=j=1;i<=n/2;i++)
    {
		for(;j<=min(i*(d+1),n);j++) sum+=num[j];
		if(sum<b) B++;
		else sum-=b;
    }
    cout<<max(A,B);
}

猜你喜欢

转载自blog.csdn.net/yzyyylx/article/details/88664582
今日推荐