P1233 木棍加工(LIS)

P1233 木棍加工(LIS)

传送门

思路:挺好的 L I S LIS LIS题,因为有两个属性,考虑将一个属性递减排序,然后对令一个属性求 L I S LIS LIS就是答案了。

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

#include
using namespace std;
typedef long long ll;
const int N=5e3+5;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair
#define fi first 
#define se second
inline void read(int &x){ 
	x=0;int w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
	for(;ch>='0'&&ch<='9';ch=getchar())
		x=(x<<3)+(x<<1)+(ch&15);
	x*=w; 
}
PII a[N];
int n,d[N],cnt=1;
bool cmp(PII a,PII b){
	return a.fi>b.fi;
}
int main(){
	read(n);
	for(reg int i=1;i<=n;i++) read(a[i].fi),read(a[i].se);
	sort(a+1,a+n+1,cmp);
	d[1]=a[1].se;
	for(reg int i=2;i<=n;i++){
		if(d[cnt]<a[i].se) d[++cnt]=a[i].se;
		else {//这里用lower_bound而非upper_bound 因为要从每个非递增子序列中选出一个组成LIS,如果相等,就会被归入另一个非递增序列中。
			int p=lower_bound(d+1,d+cnt+1,a[i].se)-d;
			d[p]=a[i].se;
		}
	}
	printf("%d\n",cnt);
	return 0;
}

你可能感兴趣的:(DP,LIS)