HDU 1667 Nested Dolls

思路: 由于一个盒子在考虑放入另一个盒子之前,要考虑两个因素,宽和高,如果我们能够消除一个因素,就在一维的条件下考虑会简单些。怎么才能降低维数呢。因为只有w小于另一个时才能才能考虑是否能放,所以我们就把w从小到大排序,这样大体盒子的先后顺序就有了,我们在比较的时候就不需要考虑宽了,因为只有后边的盒子才能容纳前边的盒子,这时我们就可以用LIS了。

先不考虑wh相同的情况,排好序后,从第一个盒子开始遍历,第一个盒子不能容纳其他任何的盒子(宽最小)。然后第二个,看他能不能容纳第一个,只需考虑h满足要求与否。然后第三个,问题来了,它既能容纳第一个,又能容纳第二个,选择哪一个,贪心就在这,它能刚好容纳谁,就容纳它,加入没有容纳那个刚好放进的,而是把一个小的多的容纳了,那么这个刚好的可能在以后就没法放进任何盒子了。

举个例子:1 8 2 4 3 3 4 5 5 4

看这个例子:h序列是: 8 4 3 5 4

现在开始实施装盒。

8单独做为一个盒。盒的序列是:8

4没有办法容纳8,所以也单独作为一个盒盒的序列是:84

3没有办法容纳前边的两个,所以也单独作为一个盒盒的序列是:843

5可以容纳4 3,最优的情况是容纳4,盒的序列是:853

4可以容纳3盒的序列是:854

假如5容纳了3,盒的序列是:845

4就没有办法45了,就单独一个盒了,最后是四个盒,看来不够优啊。

这里还要注意的是:当W相同的时,我要把h大的排在前面,假设排在后面,那么前面哪个比较小,那么后面装的肯能就会少;

该题用到了二分法;

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
struct Node
{
   int w,h;       
}doll[20024];
bool cmp( const Node &a,const Node &b )
{
   if( a.w==b.w )
     return a.h>b.h;
   return a.w<b.w;    
}
int result( int n )
{
   int sum=0,hash[20024]={0};
   for( int i=0;i<n;i++ )
   {
      int l=0,r=sum;
      while( l<r )
      {
         int k=( l + r )/2;
         if( hash[k]>=doll[i].h )
              l = k + 1;
         else r=k;       
      }
      hash[l]=doll[i].h;
      if( l==sum )sum++;
   }
   return sum;    
}
int main( )
{
     int Case,n;
     scanf( "%d",&Case );
     while( Case-- )
     {
        scanf( "%d",&n );
        for( int i=0; i<n; i++ )
        {
            scanf( "%d%d",&doll[i].w,&doll[i].h );     
        }       
        sort( doll,doll+n,cmp );
        printf( "%d\n",result( n ) );
     }  
     return 0;    
}

 

posted @ 2011-11-21 22:12  wutaoKeen  阅读(413)  评论(0)    收藏  举报