题意:
有童鞋A 和 童鞋B
A想用手里的牌尽量多地覆盖掉B手中的牌..
给出了T表示有T组样例..
每组样例给出一个n 表示A和B手中都有n张牌
接下来2*n行 有h w 分别代表A手中n张牌的高和宽 以及 B手中n张牌的高和宽
问A手中的牌最多能覆盖B多少张牌,注意,牌不能旋转,当且仅当h 和 w大于等于时能覆盖。
思路:
贪心(二维的田忌赛马?):对于A每个的每个w h,考虑覆盖B里所有w‘ <= w的并且没有被覆盖,而且最大的h' <= h。
这样,维护一个B的h值的数据结构,每次查找合适的h',multiset即可。
把A 和B 的,按照w排序,依次加入h' ,查找,删除。
我用set也给水过了。
Mark:set真是好用啊!
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<set> 5 #define N 100010 6 7 using namespace std; 8 9 set<int>s; 10 set<int>::iterator iter; 11 12 int n; 13 struct data 14 { 15 int w,h; 16 } A[N],B[N]; 17 18 bool cmp1(data p,data q) 19 { 20 return p.w < q.w; 21 } 22 23 bool find(int key) 24 { 25 iter = s.lower_bound(key + 1); 26 27 if (iter != s.begin()){ 28 iter--; 29 // printf("%d\n",*iter); 30 s.erase(iter); 31 return true; 32 } 33 return false; 34 } 35 int main() 36 { 37 int cas; 38 scanf("%d",&cas); 39 while (cas--) 40 { 41 scanf("%d",&n); 42 for (int i=1; i<=n; i++) 43 { 44 scanf("%d%d",&A[i].w,&A[i].h); 45 } 46 for (int i=1; i<=n; i++) 47 { 48 scanf("%d%d",&B[i].w,&B[i].h); 49 } 50 51 sort(A+1,A+1+n,cmp1); 52 sort(B+1,B+1+n,cmp1); 53 54 int ans = 0; 55 s.clear(); 56 57 int i = 1; 58 int j = 1; 59 while (i<=n) 60 { 61 // printf("i = %d %d %d\n",i,A[i].w,A[i].h); 62 while (j<=n && B[j].w <= A[i].w) 63 { 64 s.insert(B[j].h); 65 // printf(" %d %d %d\n",j,B[j].w,B[j].h); 66 j++; 67 } 68 int tmp = A[i].h; 69 70 if (find(tmp)) 71 { 72 ans++; 73 } 74 i++; 75 } 76 77 printf("%d\n",ans); 78 } 79 return 0; 80 }