CodeForces - 1066B Heaters(贪心)

题目: 传送门

题意: 在一个长度为n的直线上有几个加热器(用‘1’标记),开启一个加热器可以让左右两边一定长度的区间内物品都预热,求最少要开启几个加热器才能让整段直线都能预热。(如果不能则输出"-1")。

思路: 一道很明显的区间覆盖题,我们可以从贪心方面着手。如果当前1-i区间已经完全被覆盖了,则下一个最优加热器应该接近距刚好能覆盖i+1的点的加热器,如果没有则往左找最近的一个,如果无法找到则表示我们无法覆盖i+1,即我们无法覆盖整段直线,如果找到了,则更下已经完全被覆盖的区间,再进行上述操作.

ac代码:

queue<int> q;
int a[20000];

int main() {
    long long n,r;
    cin>>n>>r;
    long long haves= 0;
    long long now = r-1;//当前的最优覆盖点
    long long limit = -1;//当前已经完全覆盖的右区间
    for(int i=0;i<n;i++) {
        cin>>a[i];
        if(a[i]==1) q.push(i); // 把加入其放进队列
    }
    while(!q.empty()) {
        int i = q.front();
        q.pop();
        if(limit >= n-1) break; //如果已经覆盖整段直线
        if(i > now) {
            cout<<"-1"<<endl;
            return 0;
        }
        else {
            if(!q.empty()) {
                if(q.front()<=now) {//表示下一个是更优选项
                    continue;
                } 
                else {
                    haves++;
                    now = i+2*r-1;
                    limit = i+r-1;
                }
            }
            else {
                haves ++;
                now = i+2*r-1;
                limit = i+r-1;
            }
        }
    }
    if(limit<n-1) cout<<"-1"<<endl;
    else cout<<haves<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43305984/article/details/88785505