【upc】Simple Problem 思維LIS

有一定義域爲R的連續函數f(x),f(x)在(-∞,A)上嚴格單調遞增,在 (A,+∞)上嚴格單調遞減,其中  A
對於任意a<b≤A,均有f(a)<f(b)≤f(A) 
對於任意a>b≥A,均有f(a)>f(b)≥f(A) 
已知n個整點(xi,yi)(xi,yi是整數,xi互不相同),求f(x)最多有可能經過的點數。

輸入

輸入第一行一個整數n,表示點數。
接下來n行,每行兩個整數xi,yi,表示一個點。

輸出

輸出一行一個整數,表示f(x)最多有可能經過的點數。

樣例輸入 Copy

【樣例1】
3
3 5
4 4
5 1
【樣例2】
2
1 2
2 2

樣例輸出 Copy

【樣例1】
3
【樣例2】
1

提示

對於100%的數據:
·1≤n≤105
·xi互不相同,1≤xi,yi≤m≤105(m是一個描述xi,yi範圍的參數)

題目大意:

中文題意

題目思路:

考慮經典套路,首先按照x排序

從1開始的最長上升子序列,從n開始的最長上升子序列

然而此時枚舉最高點可能不對。

注意細節問題:A是一個整數 並沒有要求 A是給出的點的整數

所以說樣例:

2

1 2

3 2 

的答案是2

所以當A不存在這裏面時,那麼就只要求 0~A遞增 ,A~n遞減。

此時就會出現三個細節問題:(由於考慮這個不全面wa到極致,wa到上頭)

Note:q數組存儲的題目給出的信息

1.如果q[i].x - q[i-1].x >1

此時只需要在左邊找一個最長的上升子序列(從1開始),從右邊找一個最長上升子序列(從n開始)即可。因爲此時你永遠可以從中間選擇一個點使得兩邊都成立

2.如果q[i].x - q[i-1].x == 1

       並且此時q[i].y != q[i-1].y

       那麼和第一種情況相同 

            ①如果答案時q[i].y 和 q[i-1].y的結尾序列,那麼由於他們不相同,總有一個值可以成爲峯值。

            ②否則和第一種情況相同

      並且此時q[i].y == q[i-1].y(例如樣例2):

      那麼當前就只能與prea[i-2]之前的最長上升子序列的長度匹配,原理也同第一種情況

這題數據真的好,少一種情況也不行

Code:

/*** keep hungry and calm CoolGuang!***/
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define ls k<<1
#define rs k<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pp;
const ll INF=1e17;
const int maxn=1e6+6;
const int mod=998244353;
const double eps=1e-3;
inline bool read(ll &num)
{char in;bool IsN=false;
    in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
struct Line{
    int x,y,f;
    bool friend operator<(Line a,Line b){
        return a.x < b.x;
    }
}q[maxn];
ll prea[maxn],cura[maxn];
ll st[maxn];
int main(){
    read(n);
    for(int i=1;i<=n;i++) scanf("%d%d",&q[i].x,&q[i].y);
    sort(q+1,q+1+n);
    int s = 0;
    for(int i=1;i<=n;i++){
        if(!s||q[i].y>st[s]) st[++s] = q[i].y;
        else{
            int pos = lower_bound(st+1,st+1+s,q[i].y)-st;
            st[pos] = q[i].y;
        }
        prea[i] = s;
    }
    s = 0;
    for(int i=n;i>=1;i--){
        if(!s||q[i].y>st[s]){
            st[++s] = q[i].y;
        }
        else{
            int pos = lower_bound(st+1,st+1+s,q[i].y)-st;
            st[pos] = q[i].y;
        }
        cura[i] = s;
    }
    ll maxl = 0,ans = 0;
    q[0].x = -1;
    q[n+1].x = 1e7+7;
    for(int i=1;i<=n+1;i++){
        if(q[i].x-q[i-1].x>1) ans = max(prea[i-1]+cura[i],ans);
        else{
            if(q[i-1].y != q[i].y) ans = max(ans,prea[i-1]+cura[i]);
            else ans = max(ans,prea[i-2]+cura[i]);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章