题意:堆积木,就像乐高玩具那种的,下面有凹陷处,上面有突出处,这样两块积木就可以拼接了。每个积木上下的左边和中间都有拼接处,规则是下面的积木的插孔必须大于或者等于上面的插孔时,才可以堆放;问最多可以堆放多高;
简单的最长不下降子序列,注意上下可以相等,和之前做过的最长上升子序列略有不同,数据10000,n^2会超时(这道题数据很弱,如果用n^2的方法来写也能过),所以用nlogn的方法来写,利用到了二分搜索,用STL里的lower_bound()和upper_bound()解决就很方便了;
iterator lower_bound( ): 返回一个迭代器,指向键值>= key的第一个元素。
iterator upper_bound( ):返回一个迭代器,指向键值> key的第一个元素。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#define INF 0x3f3f3f3f
#define N 10010
using namespace std;
typedef struct block{
int x,y;
}block;
block p[N];
int cmp(block a,block b)//排序,先x后y,这样排出的序列中p[i].x一定是按照升序来的;
{
if(a.x==b.x)
return a.y<b.y;
else
return a.x<b.x;
}
int main()
{
int i,n,ans,dp[N];
while(1)
{
scanf("%d",&n);
if(n==0)
{
printf("*\n");
break;
}
memset(p,0,sizeof(p));
fill(dp,dp+n,INF);
for(i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
sort(p,p+n,cmp);
for(i=0;i<n;i++)
*upper_bound(dp,dp+n,p[i].y)=p[i].y;//由于排序后x是升序的,所以计算y最长不下降序列是多少就行了,又因为可以相等,所以用upper_bound();
ans=lower_bound(dp,dp+n,INF)-dp;
printf("%d\n",ans);
}
return 0;
}