zoukankan      html  css  js  c++  java
  • bzoj3126[Usaco2013 Open]Photo 单调队列优化dp

    3126: [Usaco2013 Open]Photo

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 374  Solved: 188
    [Submit][Status][Discuss]

    Description

    Farmer John has decided to assemble a panoramic photo of a lineup of his N cows (1 <= N <= 200,000), which, as always, are conveniently numbered from 1..N. Accordingly, he snapped M (1 <= M <= 100,000) photos, each covering a contiguous range of cows: photo i contains cows a_i through b_i inclusive. The photos collectively may not necessarily cover every single cow. After taking his photos, FJ notices a very interesting phenomenon: each photo he took contains exactly one cow with spots! FJ was aware that he had some number of spotted cows in his herd, but he had never actually counted them. Based on his photos, please determine the maximum possible number of spotted cows that could exist in his herd. Output -1 if there is no possible assignment of spots to cows consistent with FJ's photographic results. 

    给你一个n长度的数轴和m个区间,每个区间里有且仅有一个点,问能有多少个点

    Input

     * Line 1: Two integers N and M.

    * Lines 2..M+1: Line i+1 contains a_i and b_i.

    Output

    * Line 1: The maximum possible number of spotted cows on FJ's farm, or -1 if there is no possible solution.

    Sample Input

    5 3
    1 4
    2 5
    3 4

    INPUT DETAILS: There are 5 cows and 3 photos. The first photo contains cows 1 through 4, etc.

    Sample Output

    1
    OUTPUT DETAILS: From the last photo, we know that either cow 3 or cow 4 must be spotted. By choosing either of these, we satisfy the first two photos as well.

    HINT

     

    Source

    Gold

    定义f[i]前i个点 满足条件 最多能选多少个
    f[i]=f[j]+1 j∈[l,r]
    需要判断的是j的区间,即i从哪里转移
    1.每个区间有一个点 可以确定l是不包含i点且在完全在i点左边的区间的最靠右的左端点
    2.每个区间仅有一个点 可以确定r是包含i点的区间最靠左的左端点-1
    可以单调队列维护 也可以数据结构维护

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define N 200050
    using namespace std;
    int n,m,f[N],q[N],l[N],r[N];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n+1;i++)r[i]=i-1;
        for(int i=1;i<=m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            r[b]=min(r[b],a-1);
            l[b+1]=max(l[b+1],a); 
        }
        for(int i=2;i<=n+1;i++)l[i]=max(l[i],l[i-1]);
        for(int i=n;i>=1;i--)r[i]=min(r[i],r[i+1]);
        int h=1,t=1,j=1;
        for(int i=1;i<=n+1;i++){
            while(j<=r[i]&&j<=n){
                if(f[j]==-1){j++;continue;}
                while(h<=t&&f[j]>=f[q[t]])t--;
                q[++t]=j++;
            }
            while(h<=t&&q[h]<l[i])h++;
            if(h<=t)f[i]=f[q[h]]+1;
            else f[i]=-1;
        }
        printf("%d
    ",f[n+1]==-1?-1:f[n+1]-1);
        return 0;
    }
  • 相关阅读:
    mysql 触发器
    Yii 1.0 基础
    python解释执行原理(转载)
    python中使用selenium调用Firefox缺少geckodriver解决方法
    Python中os和shutil模块实用方法集锦
    pytesseract使用
    anaconda安装第三方库
    anaconda spyder异常如何重新启动
    windows下python3.6 32bit 安装django
    设置SO_RECVBUF和SO_SENDBUF套接字选项
  • 原文地址:https://www.cnblogs.com/wsy01/p/8116431.html
Copyright © 2011-2022 走看看