2013
12-21

# Nested Dolls

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 he wonders if there is another way of nesting them so he will end up with fewer 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 will fit in another doll of width w2 and height h2 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?

On the first line of input is a single positive integer 1 <= t <= 20 specifying the 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.

For each test case there should be one line of output containing the minimum number of nested dolls possible.

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

1
2
3
2

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include <iostream>
using namespace std;
const int N=20000+5;
struct doll
{
int w;
int h;
}d[N];
int dp[N];//储存排序结果
bool cmp(doll d1,doll d2)
{
return d1.w>d2.w||(d1.w==d2.w&&d1.h<d2.h);//注意这里排序是避免相同的宽度被包含
}
int main()
{
int T,i,mxlen,j,n,r,l,mid;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d%d",&d[i].w,&d[i].h);
sort(d,d+n,cmp);
memset(dp,0,sizeof(dp));
mxlen=0;
for(i=0;i<n;i++)
{   l=0;
r=mxlen;
while(l<r)//利用二分法进行排序找到适合d[i].h的插入的位置
{
mid=(l+r)/2;
if(dp[mid]<=d[i].h)
l=mid+1;
else
r=mid;
}
dp[l]=d[i].h;//在l位置上插入d[i].h
if(l==mxlen)//如果找到的位置刚好在当前序列的尾端则插入
mxlen++;
}
printf("%d\n",mxlen);
}
return 0;
}

1. 我还有个问题想请教一下，就是感觉对于新手来说，递归理解起来有些困难，不知有没有什么好的方法或者什么好的建议？