SPOJ 3943 Nested Dolls

【SPOJ 3943 Nested Dolls】

Time Limit: 156MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu 

Description】Dilworth is the world's most prominent collector of Russian nested dolls:he literally has thousands of them! You know, the wooden hollow dolls of different sizes of which the smallest doll is contained in the second smallest,and this doll is in turn contained in the next one and so forth. One day hewonders if there is another way of nesting them so he will end up withfewer nested dolls? After all, that would make his collection even more magnificent! He unpacks each nested doll and measures the width and height of each contained doll. A doll with width w1 and height h1 willfit in another doll of width w2 and height h= if and only if w1 < w2 and h1 < h2. Can you help him calculate the smallest number of nested dolls possible to assemble from his massive list of measurements?

Input】On the first line of input is a single positive integer 1 ≤ t ≤ 20 specifyingthe number of test cases to follow. Each test case begins with a positive integer 1 ≤ m ≤ 20000 on a line of itself telling the number of dolls in the test case. Next follow 2m positive integers w1, h1,w2, h2, ... ,wm, hm, where wi is the width and hi is the height of doll number i. 1 ≤ wi, hi ≤ 10000 for all i.【SAMPLE INPUT】

4

3

20 30 40 50 30 40

4

20 30 10 10 30 20 40 50

3

10 30 20 20 30 10

4

10 10 20 30 40 50 39 51

Output】 For each test case there should be one line of output containing the minimumnumber of nested dolls possible.

【SAMPLE OUTPUT】

1

2

3

2

【Hint】Time limit: 0.156s-0.259s Source limit: 50000B Memory limit: 1536MB Cluster: Cube (Intel G860) Languages: All except: ERL JS NODEJS PERL 6 VB.net Resource: Nordic 2007

【題目中文大意】現在n(<=20000)個俄羅斯套娃,每個都有寬度wi和高度hi(均小於10000),要求w1<w2並且h1<h2的時候纔可以合併,問最少能剩幾個。

【題目思路】題目要求wi>wj && hi>hj才能合併。 那麼可以先貪心使這個序列滿足wi>wj,那麼不滿足的就是hi<=hj,如果wi==wj,那麼就滿足排序hi<hj,這樣就相當於是在排序後h序列中找出一個LIS(最長不下降子序列)**LIS**可以用DP(我記得我寫過dp的LIS,,這是一個坑,記得填坑!!),O(n)查找,,,這裏講O(logn)二分查找也可以用upper_bound(),不過這個他是每一個都加入,再找,感覺看的不是很懂,感興趣的同學給個友鏈友鏈點這裏

代碼

//wi>wj hi>hj 那麼可以先貪心使這個序列滿足wi>wj,,如果wi==wj,那麼就滿足hi<hj
//然後再求LIS(最長不下降子序列),就可以求出有多少個不滿足條件了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define cle(x) memset(x,0,sizeof(x))
#define clemax(x) memset(x,127,sizeof(x))
using namespace std;
const int N=20020;
struct ii{
 int w,h;
 ii(int w=0,int h=0):w(w),h(h){ }
 bool operator <(const ii &a)const{
  if(w^a.w)return w>a.w;
  return h<a.h;
 }
}child[N];
int last[N],ans,n;
int find(int x){
 int l=1,r=ans;
 int tmp=0;
 while(l<=r){
  int mid=(l+r)>>1;
  if(last[mid]<=x)tmp=mid,l=mid+1;//找到最後一個小於等於他的
  else r=mid-1;
 }
 return tmp;
}
int T;
int main(){
 freopen("spoj.in","r",stdin);
 freopen("spoj.out","w",stdout);
 scanf("%d",&T);
 for(int o=1;o<=T;o++){
  scanf("%d",&n);
  cle(child),clemax(last);
  ans=0;
  for(int i = 1; i<= n; i++)
   scanf("%d%d",&child[i].w,&child[i].h);
  sort(child+1,child+n+1);
  for(int i = 1; i<= n; i++)//求LIS也就是所剩下的
  {
   int tmp=find(child[i].h);
   if(last[tmp+1]>child[i].h)last[tmp+1]=child[i].h;
   ans=max(ans,tmp+1);
  }
  printf("%d\n",ans);
 } 
}


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