HDU 1667 Nested Dolls
思路: 由于一个盒子在考虑放入另一个盒子之前,要考虑两个因素,宽和高,如果我们能够消除一个因素,就在一维的条件下考虑会简单些。怎么才能降低维数呢。因为只有w小于另一个时才能才能考虑是否能放,所以我们就把w从小到大排序,这样大体盒子的先后顺序就有了,我们在比较的时候就不需要考虑宽了,因为只有后边的盒子才能容纳前边的盒子,这时我们就可以用LIS了。
先不考虑w和h相同的情况,排好序后,从第一个盒子开始遍历,第一个盒子不能容纳其他任何的盒子(宽最小)。然后第二个,看他能不能容纳第一个,只需考虑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就没有办法4和5了,就单独一个盒了,最后是四个盒,看来不够优啊。
这里还要注意的是:当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;
}

浙公网安备 33010602011771号