poj2373 (monotone queue optimization dp)

Portal

Each question is intended for a sprinkler radius [A, B], each cow has a section of its own [s, e], this range can be covered by a sprinkler.

Requires the entire interval [1, L] (L <= 1e6) is covered does not overlap, at least to the number of sprinklers, sprinklers should not exceed the range of the overall range interval.


 Since an interval [s, e] only covered by a sprinkler, so [s + 1, e-1] can not be a certain range of watering sprinkler right endpoint.

We not_r [] to make a mark.

L to see the range of 1e6, we should know is O (n) algorithm to use.

Set f [i] represents the number of sprinklers i to the desired position. (I must be the right end point ).

f[i]=min(f[j])+1(A<=(i-j)/2<=B)

Direct cycle time O (n ^ 2) optimization considerations.

We found that for point i, j must be used for a continuous range, so a single team to maintain a minimum of f [j].

Since a j can be used depends on its location meets limited, id stored at the queue with the subscript.

Because i was right point, so when the cycle, we are an even number increases.

#include<cstdio>
#include<iostream>
#include<cstring>
#define LL long long
#define INF 2100000000
#define N 1000003
#define re register
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
void print(int x)
{
    if(x<0)x=-x,putchar('-');
    if(x>9)print(x/10);
    putchar(x%10+'0');
}
int id[N],f[N],q[N],not_r[N];
int main()
{
    int n=read(),l=read();
    int a=read(),b=read();
    for(int i=1;i<=n;++i)
    {
        int s=read(),t=read();
        for(int j=s+1;j<t;++j)
          not_r[j]=1;
    }
    for(int i=1;i<=l;++i)f[i]=INF;
    int h=1,t=0,head=1,tail=0;
    id[++t]=0;
    for(int i=2;i<=l;i+=2)//偶数个的加 
    {
        if(not_r[i])continue;
        while(h<=t&&(i-id[h])/2>=a)
        {
            while(head<=tail&&f[q[tail]]>=f[id[h]])tail--;
            q[++tail]=id[h];//加入q里了,就可以移出id了 
            h++;
        }
        while(head<=tail&&(i-q[head])/2>b)head++;
        if(head<=tail)
        {
            f[i]=f[q[head]]+1;
            id[++t]=i;
        }
    }    
    if(f[l]!=INF)printf("%d\n",f[l]);
    else printf("-1\n");
    
}
/*
*/
View Code

 

Guess you like

Origin www.cnblogs.com/yyys-/p/11640941.html