HDU 4268Alice and Bob(贪心+SET维护)

题意:

有童鞋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 }
hdu 4268

 

转载于:https://www.cnblogs.com/wangsouc/articles/3269650.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值