CF1066B Heaters(贪心)

题意描述:

Vova先生的家可以看作一个n×1的矩形,寒冷的冬天来了,Vova先生想让他的家里变得暖和起来。现在我们给你Vova先生家的平面图,其中111表示这个地方是加热炉,0表示这个地方什么也没有。所有加热器都有一个加热半径r,一个位于ai加热器可以加热[ai−r+1,ai+r−1]的范围。现在,Vova先生想让他的整个家都变得暖和,一开始所有的加热器都是关闭的,请你求出Vova先生最少要开几个加热器才能使整个家变得暖和

输入输出格式:

输入格式:

第一行:两个整数n,r(1≤n,r≤1000),含义如上

第二行,n个整数,表示Vova家的地图

输出格式:

一个整数,表示Vova先生至少要打开几个加热器

思路:

还是很水

因为我们要尽可能少,所以我们要用贪心的思想

我们从最左边开始扫,扫到一个没有被加热的点,我们就以这个点为起点向右扫,扫到能加热他的离他最远的一个加热器打开

(贪心的正确性在于这个加热器离他最远且能将它加热,如果选更近的则不更优,选更远的就加热不了他了)

然后将该加热器能加热的范围内的点打标记,继续扫下去即可

最坏时间复杂度O(N^2)

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rii register int i
#define rij register int j
using namespace std;
int n,r,jz[4005],jrq[4005],bj[4005],ans;
int main()
{
    int cnt=0;
    scanf("%d%d",&n,&r);
    for(rii=1;i<=n;i++)
    {
        scanf("%d",&jz[i]);
        if(jz[i]==1)
        {
            cnt++;
            jrq[cnt]=i;
        }
    }
    for(rii=1;i<=n;i++)
    {
        if(bj[i]==0)
        {
            int wz=0;
            for(rij=1;j<=r;j++)
            {
                if(i+j-1<=n)
                {
                    if(jz[i+j-1]==1)
                    {
                        wz=max(wz,i+j-1);
                    }
                }
                if(i-j+1>=1)
                {
                    if(jz[i-j+1]==1)
                    {
                        wz=max(wz,i-j+1);
                    }
                }
            }
            for(rij=1;j<=r;j++)
            {
                if(wz-j+1>0)
                {
                    bj[wz-j+1]=1;
                }
                bj[wz+j-1]=1;
            }
            ans++;
            if(wz==0)
            {
                printf("-1");
                return 0;
            }
        }
    }
    printf("%d",ans);
}

猜你喜欢

转载自www.cnblogs.com/ztz11/p/9807529.html
今日推荐