EOJ-1765 Nested Dolls

http://acm.cs.ecnu.edu.cn/problem.php?problemid=1765

题意:给出一系列物体的宽与高,满足w1<w2且h1<h2的情况下可以把物品1装在物品2中(可以看成一个),问最少剩余几个物品。

思路:为方便则先按宽度排序,就保证后面的物品一定不能放进前面的物品中,每次只要对每个物品前面的物品进行搜索(即宽度小于该物品),若满足高度比该物品高度小的就列入候选,最终选择候选最大的那个物品装进该物品中(贪心思路,如果每次把前面物品装进后面物品中尽可能选择最大的,那剩余小的可以尽可能让后续的物品装进,而对于某物品来说,选择谁去装它并不会影响结果),若找不到满足要求的物品,则说明需要另开一个了。每次装完后需要更新把装进去的物品从能选择的集合中删除。

而对于相同宽度的物品,高度必须按照降序排序,这样进行前面的搜索时就不会把相同宽度的也纳入候选

实现用了multiset (不去重的集合) 和low_bound (找到第一个大于等于指定值的元素)

 1 #include<map>
 2 #include<set>
 3 #include<list>
 4 #include<cmath>
 5 #include<ctime>
 6 #include<queue>
 7 #include<stack>
 8 #include<cctype>
 9 #include<cstdio>
10 #include<string>
11 #include<vector>
12 #include<cstdlib>
13 #include<cstring>
14 #include<iostream>
15 #include<algorithm>
16 using namespace std;
17 struct node{
18     int w,h;
19 }a[20005];
20 bool cmp(node a,node b){
21     if(a.w!=b.w)
22         return a.w<b.w;
23     else 
24         return a.h>b.h;
25 }
26 int main(){
27     //freopen("1765#1.in","r",stdin);
28     //freopen("out.txt","w",stdout);
29     int T;
30     cin>>T;
31     while(T--){
32         int n;
33         scanf("%d",&n);
34         for(int i=0;i<n;i++)
35             scanf("%d%d",&a[i].w,&a[i].h);
36         sort(a,a+n,cmp);
37         multiset<int> s;
38         int cnt=0;
39         for(int i=0;i<n;i++){
40             multiset<int>::iterator it=s.lower_bound(a[i].h);
41             if(it==s.begin()) cnt++;    //找不到比它更小的元素
42             else s.erase(--it);            //找到则删除之前的元素(即小于给定值的极大值)    
43             s.insert(a[i].h);
44         }
45         printf("%d\n",cnt);
46     }
47     return 0;
48 }
View Code

 

posted on 2013-07-23 03:54  KimKyeYu  阅读(250)  评论(1编辑  收藏  举报

导航