NKOI 3662 划区灌溉

来源:互联网 发布:中国知网专利数据库 编辑:程序博客网 时间:2024/09/21 08:48

划区灌溉

Time Limit:10000MS  Memory Limit:65536K
Total Submit:47 Accepted:25
Case Time Limit:1000MS

Description

约翰的奶牛们发现山脊上的草特别美味.为了维持草的生长,约翰打算安装若干喷灌器.为简化问题,山脊可以看成一维的数轴,长为L(1≤L≤10^6),而且L-定是一个偶数.每个喷灌器可以双向喷灌,并有确定的射程,该射程不短于A,不长于B,A,B(1≤A≤B≤10^3)都是给出的正整数.它所在位置的两边射程内,都属它的灌溉区域.注意,一个喷灌器往左右两边喷射的距离是一样的,比如往左喷的距离是x,那么往右也是x,(A<=x&lt;=B)。
现要求山脊的每一个区域都被灌溉到,喷灌器不能将水喷到山脊以外的区域,而且喷灌器的灌溉区域不允许重叠, 约翰有N(1≤N≤10^3)只奶牛,每一只都有特别喜爱的草区,第i奶牛喜爱的草区是[Si,Ei],不同奶牛的草区可以重叠(Ei-Si<=2*B).现要求,每只奶牛的草区仅被一个喷灌器灌溉. 寻找最少需要的喷灌器数目.

Input

第一行,两个整数N和L
第二行,两个整数A和B
接下来N行,每行两个整数S和E(0 <= S < E <= L),表示每头奶牛喜欢的草区的起止位置

Output

一行,一个整数,表示最少需要的喷灌器的数量,若无解,输出-1

Sample Input

样例输入1:2 81 26 73 6样例输入2:4 20210 1221 2732 39103 121163 180

Sample Output

样例输出1:3样例输出2:10

Source

usaco 2004 dec gold


分析1: 题意告知,一个喷灌器可以往左右两边喷射x远的距离,A<=x<=B为方便讨论,我们可以将喷射器看做只能往左喷,往左喷射的距离是2*A到2*B之间。分析2:我们考虑最简单的情况,没有奶牛:既是覆盖L区域,最少需要多少个喷灌器 者就是一个简单的背包DPDp[i]表示在覆盖区间[1,i],所需最少喷灌器数量。并且在第i位置要安置一个喷灌器。Dp[i]=Min{ Dp[k] }+1     i-2*B<=k<=i-2*A0<=i<=L分析3:上述方程是O(n^2)的,显然会超时。我们注意到方程中Min{Dp[k]} 其实是在[i-2*B,i-2*A]区间中找一个最小的Dp[]值求区间最小值,我们可以考虑"滑动窗口"模型,采用单调队列这样时间复杂度就能降到O(n)分析4:哪些位置是不能放喷灌器呢?1.根据题意,L是偶数,喷灌器不能喷射到[1,L]区间之外,也就是说只能在偶数位置安置喷灌器2.每头奶牛所管辖区间只能被一个喷灌器覆盖,  也就是说对于一头所在区间为[St,Ed]的奶牛,[St+1,Ed-1]位置是不能安放喷灌器的。  只能安置在St或Ed位置结论: 综合上述分析,我们只需预先将不能安放喷灌器的位置i标记为Mark[i]=true,然后再跑一遍用单调队列优化的DP就可以解决这道题目了。时间复杂度为O(n)
#include<cstdio>#include<iostream>#include<queue>#define inf 999999999using namespace std;int n,l,a,b;deque<int>q;bool check[1000001];int f[1000001];int main(){scanf("%d%d%d%d",&n,&l,&a,&b);int i,j,k,x,y;for(i=1;i<=n;i++){scanf("%d%d",&x,&y);for(j=x+1;j<y;j++)check[j]=true;//奶牛的区域内设为不能放置}for(i=1;i<=l;i++){f[i]=inf;while(!q.empty()&&q.front()<i-2*b)q.pop_front();//从队首删除喷不到该位置的元素if(!check[i]&&i%2==0)    if(!q.empty())f[i]=min(f[i],f[q.front()]+1);//由于单调性,队首元素的dp值一定最小        if(i-2*a+1>=0&&!check[i-2*a+1]&&(i-2*a+1)%2==0){//为讨论i+1位置做准备,讨论区间[i-2*B,i-2*A]右边i-2*A+1位置是否入队
        while(!q.empty()&&f[i-2*a+1]<f[q.back()])q.pop_back();//维护单调性        q.push_back(i-2*a+1);} }printf("%d",f[l]==inf?-1:f[l]);}

0 0
原创粉丝点击