The 2014 ACM-ICPC Asia Shanghai Regional Contest - I - Defeat the Enemy (贪心+multiset)UVALive - 7146

题意:

交战双方,我方n只军队,敌方m只军队,每只军队都有生命值和攻击力。两军交战,本身生命值减去对方的攻击力,若剩余生命值小于等于0那么阵亡。若我军能消灭敌军,最多生还多少队伍?不能的话,输出-1。


思路:

贪心做法,先将我方军队按攻击力升序,敌方军队按生命值升序。用multiset维护我方军队的生命值,加入multiset中的军队,倘若其攻击力都能消灭敌方的当前和以后的队伍。对于敌方的一只军队,找到我方中,能消灭他的,且不被他消灭的最小生命值,倘若不存在,则牺牲multiset中最小的那个值(田忌赛马的感觉)。


ps:

这里的multiset利用迭代器就行操作,因为删除元素时不像set那样,比如{1,1,2}中想要删除1,那么最后的结果是{2},而不是{1,2}。


代码:

#include
#include
#include
#include
using namespace std;

struct troop
{
	int harm,life;
}w[100010],d[100010];


bool cmp1(troop a,troop b)//攻击力排序
{
	return a.harm>b.harm;
}


bool cmp2(troop a,troop b)//生命值排序
{
	return a.life>b.life;
}

int main()
{
	int t,cnt,n,m,p=0;
	bool flag;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		printf("Case #%d: ",i);
		scanf("%d%d",&n,&m);
        for(int j=0;j defense;
		p=cnt=0;//cnt记录阵亡的人数
		flag=true;
        for(int j=0;j=d[j].life)
				{
					defense.insert(w[k].life);
					p++;
				}
				else break;
			}
			//如果我方剩余军队不能消灭敌方队伍退出
			if(defense.empty())
			{
				flag=false;
				break;
			}
			else
			{
			   //能不损失军队,则用我方生命值恰好高于敌方的去消灭
			   //倘若必须损失军队,则损失当前生命值最低的
			   multiset  ::iterator it;
               it=defense.upper_bound(d[j].harm);
			   if(it!=defense.end())
				   defense.erase(it);
			   else
			   {
				   defense.erase(defense.begin());
				   cnt++;
			   }
			}
		}
		if(!flag)
			printf("-1\n");
		else
			printf("%d\n",n-cnt);
	}
	return 0;
}


你可能感兴趣的:(acm-icpc,数据结构,贪心,数据结构,贪心)