ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[USACO13OPEN] Photo

2019-11-08 12:56:24  阅读:296  来源: 互联网

标签:his minl 端点 int Photo USACO13OPEN maxl cows


[USACOW13OPEN] Photo

这是一个很棒的动态规划题

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.

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.
Examples of input and output

Input #1
5 3
1 4
2 5
3 4
Output #1
1

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

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.





看到讨论版说可以用差分约束可以做,但是因为不会的缘故所以我没有选择差分约束。

概括一下题目大意,给定了一些区间:\(R_i=[L_i,R_i]\),每个区间上有且仅有一个点。问最多几个点。


emmmmmmmmmmm……
容易得到状态转移方程:


(其实真的一点都不容易,我想了不知道多久……最后还偷偷看了几行题解)
\[ f[i]=f_{max}[j]+1,j \in \{ 某种条件 \} \]
其中,\(f[i]\)表示在\(i\)处放一个点,算上这一个点,从\(1\)到\(i\)位置最多放置几个点。



很直接的方程,问题在于这个“某种条件”。

考虑“某种条件”的两个端点值。


\(1^{\circ}\)左边最远去哪里?
我们希望\(j\)的值越小越好,但是不能太小。比如说从\(i\)到\(j\)居然越过了某个整个的区间,这是不可能的。因为根据状态转移方程的定义,\((j,i]\)中间是不可以放置点的。
所以,大概可以知道这个左端点的值最小可以去到一个:

  1. 不覆盖\(i\)的;
  2. 左端点值尽量大的;

区间的左端点。把它记为\(maxl[i]\).


\(2^{\circ}\)右边最远去哪里?
我们希望\(j\)的值越大越好,但是不能太大。比如说从\(i\)到\(j\)居然在同一个区间里,这是不可能的。因为同一个区间有且仅有一个点。
所以,大概可以知道这个右端点的值最大可以去到一个:

  1. 覆盖\(i\)的;
  2. 左端点值尽量小的;

区间的左端点的再左边一个单位的位置。把它记为\(minl[i]\).

关于\(maxl[i]\)和\(minl[i]\)的求法,递推即可。

读入\([L_i,R_i]\)的时候:

    minl[r]=min(minl[r],l);
    maxl[r+1]=max(maxl[r+1],l);

然后扫描:

    for(int i=1;i<=n+1;i++)
        maxl[i]=max(maxl[i-1],maxl[i]);
    for(int i=n ;i>=0;i--)
        minl[i]=min(minl[i+1],minl[i]);

因为我们每次都是取\([maxl[i],minl[i])\)的最大值进行状态转移,还注意到\(maxl[]\)和\(minl[]\)都是递增数列;

这就非常开心了,直接上单调队列优化。

关于非法情况,即要转移给\(f[i]\)的\(j\)不存在,也即,队列空,那么\(f[i]=-1\);

最后弄个假的点\(n+1\),注意这个点是假的所以再状态转移的时候不能+1.

最终的状态转移方程:
\[ f[i]=f[Q.front()]+(!(i==n+1)),\ Q.front() \ is \ the \ maximum \ value \ in [maxl[i],minl[i]). \]

*关于这个状态转移方程其实我仍存疑问。在OJ的评测中,写成\(f[i]=f[Q.back()]+(!(i==n+1))\)也是可以AC的。这可能是一个很傻的问题,但是知道真相的人请务必留言。

码字好累啊……




コード:

#include<bits/stdc++.h>
using namespace std;
const int N=200005,INF=0x3f3f3f3f,M=100005;
int maxl[N],minl[N],f[N];
int tot=0,ans=0;
int n,m;
bool ban[N];
deque<int> Q;
inline int read()
{
    char c=getchar();int x=0;
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())
        x=x*10+c-'0';
    return x;
}


int main()
{
    n=read();m=read();
    for(int i=1;i<=n+1;i++)minl[i]=i;
    for(int i=1;i<=m;i++)
    {
        int l=read();
        int r=read();
        minl[r]=min(minl[r],l);
        maxl[r+1]=max(maxl[r+1],l);
    }
    for(int i=1;i<=n+1;i++)
        maxl[i]=max(maxl[i-1],maxl[i]);
    for(int i=n ;i>=0;i--)
        minl[i]=min(minl[i+1],minl[i]);
    
    int j=1;
    Q.push_back(0);
    for(int i=1;i<=n+1;i++)
    {
        for(;j<minl[i];j++)
        {
            if(f[j]!=-1)
            {
                while(!Q.empty()&&f[Q.back()]<f[j])Q.pop_back();
                Q.push_back(j);
            }
        }
        while(!Q.empty()&&Q.front()<maxl[i])Q.pop_front();
        if(!Q.empty())
            f[i]=f[Q.front()]+(!(i==n+1));
        else
            f[i]=-1;
    }
    cout<<f[n+1];
    return 0;
}

标签:his,minl,端点,int,Photo,USACO13OPEN,maxl,cows
来源: https://www.cnblogs.com/kion/p/11819379.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有