• BZOJ1986: [USACO2004 Dec] Dividing the Path 划区灌溉


    L<=1000000的土地上用长度在2*A~2*B的线段覆盖所有点,且给定n<=1000个区间,每个区间上只允许有一条线段,求最少多少线段,无解-1。

    f[i]表示填前i个土地最少线段,f(i)=f(j)+1,2*A<=i-j<=2*B,用个单调队列就行。注意区间是左闭右开。

    至于那些坏区间,如果某个状态在覆盖了该点的区间的最远的右端点,那是合法的,否则一旦它被覆盖就是不合法状态。

    为了处理这种情况,将区间按左端点排序,走到一个点时,若该点满足上面的情况,那就说明有一些区间的左端点<=i,把这些区间的右端点取个最大值来比较即可。出现这种情况后,把当前状态,以及当前状态到最远被覆盖区间右端点这些状态全部变成inf,然后i跳到那个右端点就可以做了。

    不过,单调队列的节点添加不稳定,因此记个“单调队列加到哪里了”,这样就不怕跳来跳去的i了。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 #include<iostream>
     6 using namespace std;
     7  
     8 int n,L,A,B;
     9 #define maxn 1000011
    10 struct Cow
    11 {
    12     int l,r;
    13     bool operator < (const Cow &b) const {return l<b.l;}
    14 }a[maxn];
    15 int f[maxn],que[maxn],head,tail;
    16 const int inf=0x3f3f3f3f;
    17 int main()
    18 {
    19     scanf("%d%d%d%d",&n,&L,&A,&B);
    20     for (int i=1;i<=n;i++)
    21         scanf("%d%d",&a[i].l,&a[i].r),a[i].l++;
    22     sort(a+1,a+1+n);
    23     head=tail=0;
    24     int last=0,k=1;
    25     if (L&1) puts("-1");
    26     else
    27     {
    28         for (int i=2;i<=L;i+=2)
    29         {
    30             while (head<tail && que[head]<i-2*B) head++;
    31             for (int j=last;j<=i-2*A;j+=2)
    32             {
    33                 while (head<tail && f[que[tail-1]]>=f[j]) tail--;
    34                 que[tail++]=j;
    35             }
    36             last=max(last,i-2*A+2);
    37             int far=0;
    38             while (k<=n && i>=a[k].l)
    39             {
    40                 far=max(far,a[k].r);
    41                 k++;
    42             }
    43             if (i<far)
    44             {
    45                 int tmp=((far&1)?far+1:far)-2;
    46                 for (;i<tmp;i+=2) f[i]=inf;f[i]=inf;
    47                 last=max(last,i-2*B+2);
    48                 continue;
    49             }
    50             if (head<tail) f[i]=f[que[head]]+1;
    51             else f[i]=inf;
    52         }
    53         printf(f[L]>=inf?"-1
    ":"%d
    ",f[L]);
    54     }
    55     return 0;
    56 }
    View Code
  • 相关阅读:
    MFC单文档视图设置背景
    原来这就是命令行下的“学生信息管理系统”
    C语言中数组&取地址的问题
    《逐梦旅程-Windows游戏编程之从零开始》 勘误
    杭电ACM 1003 ( 动态规划法 水题)
    《编程之美》
    [蓝桥杯][2014年第五届真题]地宫取宝
    [蓝桥杯][2013年第四届真题]危险系数
    2142: 逛超市(zznuoj)
    2141:2333(zznuoj)
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7574743.html
Copyright © 2020-2023  润新知