I http://acm.hust.edu.cn/vjudge/contest/view.action?cid=84975#problem/I
题意:我方有n个士兵,敌方有m个士兵,每个士兵有攻击力和防御力,我方一个兵只能选择对方一个兵去战斗,即使我方幸存了也不能再去和别的敌人战斗,一场战斗中防御力小于等于对方攻击力的兵会死,我们需要选出一个方案使得杀死对面所有兵,且我们存活的兵尽量多。
解法:先把我军按照攻击力从大到小排序,敌军按照防御力从大到小排序,然后依次枚举敌军士兵,对每个敌军士兵,我们把攻击力大于等于其防御力的都存到map中,存我军的防御力。map中的都一定能杀死对手。所以我们在map中二分出第一个防御力大于敌军攻击力的,那么选择他可以使得幸存的人数多一个,并且防御力最节省。贪心。
1 //#define txtout 2 //#define debug 3 #include<cstdio> 4 #include<algorithm> 5 #include<map> 6 using namespace std; 7 const int M=1e5+10; 8 map<int,int> mp; 9 map<int,int>::iterator it; 10 struct G{ 11 int attack,defense; 12 }our[M],his[M]; 13 int n,m; 14 bool cmp_defense_de(const G &a,const G &b){ 15 return a.defense>b.defense; 16 } 17 bool cmp_attack_de(const G &a,const G &b){ 18 return a.attack>b.attack; 19 } 20 int solve(){ 21 sort(our,our+n,cmp_attack_de); 22 sort(his,his+m,cmp_defense_de); 23 mp.clear(); 24 int our_id=0; 25 int result=0; 26 for(int i=0;i<m;i++){ 27 while(our_id<n&&our[our_id].attack>=his[i].defense){ 28 mp[our[our_id].defense]++; 29 our_id++; 30 } 31 if(mp.empty()) return -1; 32 it=mp.upper_bound(his[i].attack); 33 if(it==mp.end()){ 34 it=mp.begin(); 35 } 36 else{ 37 result++; 38 } 39 if(it->second==1){ 40 mp.erase(it); 41 } 42 else{ 43 mp[it->first]--; 44 } 45 } 46 result+=n-our_id; 47 for(it=mp.begin();it!=mp.end();it++){ 48 result+=it->second; 49 } 50 return result; 51 } 52 int main(){ 53 #ifdef txtout 54 freopen("in.txt","r",stdin); 55 freopen("out.txt","w",stdout); 56 #endif // txtout 57 int t; 58 while(~scanf("%d",&t)){ 59 int cas=1; 60 while(t--){ 61 scanf("%d%d",&n,&m); 62 for(int i=0;i<n;i++){ 63 scanf("%d%d",&our[i].attack,&our[i].defense); 64 } 65 for(int i=0;i<m;i++){ 66 scanf("%d%d",&his[i].attack,&his[i].defense); 67 } 68 printf("Case #%d: %d ",cas++,solve()); 69 } 70 } 71 return 0; 72 }
end