有一定義域爲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;
}