题目:HDU4268(贪心)
比赛的时候没做出来,后来几天也没做这个题,今天搞了一下午,参考了几大牛人的博客,才弄懂..
题意是Alice和Bob都有N张卡片,卡片各有尺寸,Alice拿自己的卡片分别去盖Bob的,给出每张卡片的尺寸,问最多可以盖住多少张。
先说一下我错误的解题方法,主要思想就是拿最大的去盖最大的。分别对Alice和Bob的卡片在两个set中进行排序(排序是自动的),
按卡片的h降序排,h相同时按w的降序排。然后以Bob的set做循环,取Alice的set首端的卡片去盖,能盖住则删去,代码如下:
#include <iostream>
//#include <fstream>
#include <set>
#define FOR(a,b) for(int i = (a);i < (b);i ++)
using namespace std;
class Card
{
public:
int h,w;
bool operator<(const Card& c) const //插入set时自动排序,要自定义"<"操作符
{
if( h == c.h) return w < c.w;
return h < c.h;
}
bool CanCover(const Card& c) const
{
return (h >= c.h && w >= c.w);
}
};
int main()
{
//ifstream cin("in.txt");
multiset<Card> Alice,Bob;
multiset<Card>::iterator ap,bp;
Card c;
int t,n,ans;
cin>>t;
while (t --)
{
Alice.clear();
Bob.clear();
ans = 0;
cin>>n;
FOR(0,n)
{
cin>>c.h>>c.w;
Alice.insert(c);
}
FOR(0,n)
{
cin>>c.h>>c.w;
Bob.insert(c);
}
ap = Alice.begin();
while (ap != Alice.end())
{
bp = Bob.begin();
if(ap->CanCover(*bp))
{
Bob.erase(bp);
ans ++;
}
ap ++;
}
cout<<ans<<endl;
}
}
我拿着这个代码提交了好几次都不对,然后就去参考了牛人的博客,看了半天才发现自己陷入了思维定势,正确思维应该是,对于Bob的每张卡片,把Alice的满足高度大于这张卡片的所有卡片组成一个集合(set),从集合中找w最接近的卡片,找到则从集合中删去。
正确的代码如下:
#include <iostream>
//#include <fstream>
#include <set>
#include <algorithm>
#define FOR(a,b) for(int i = (a); i < (b); i ++)
using namespace std;
const int maxnum = 100005;
struct Card
{
int h,w;
bool operator<(Card& c)
{
return (h < c.h);
}
};
Card Alice[maxnum],Bob[maxnum];
int main()
{
//ifstream cin("in.txt");
multiset<int> mi;
multiset<int>::iterator mit;
int t,n,ans;
cin>>t;
while (t --)
{
cin>>n;
memset(Alice,0,sizeof(Card)*n);
memset(Bob,0,sizeof(Card)*n);
mi.clear();
ans = 0;
FOR(0,n)
{
cin>>Alice[i].h>>Alice[i].w;
}
FOR(0,n)
{
cin>>Bob[i].h>>Bob[i].w;
}
sort(Alice,Alice+n);
sort(Bob,Bob+n);
int p = 0;
FOR(0,n)
{
while (p < n && Bob[p].h <= Alice[i].h)
{
mi.insert(Bob[p].w);
p ++;
}
if(mi.size())
{
mit = mi.lower_bound(Alice[i].w);
if(mit == mi.end()) mit --;
if(mit != mi.begin() && Alice[i].w < *mit) mit --;
if(Alice[i].w >= *mit)
{
mi.erase(mit);
ans ++;
}
}
}
cout<<ans<<endl;
}
}