您的位置:首页 > 理论基础 > 计算机网络

HDU4415 Assassin’s Creed 2012ACM/ICPC 杭州赛区网络赛 F

2012-09-27 20:02 453 查看
HDU4415(枚举,贪心)

大意:

杀手有把耐久为m的“袖口刀”,一共有n个敌人,每个敌人都有防御值Ai ,杀死一个为Ai的敌人则m -= Ai,每个敌人有“能量刀”,杀死敌人后可以获取敌人的能量刀,能量值Bi是几就可以再杀几个人,刀可以叠加,Bi为0就是这个敌人没有能量刀。问消耗尽量小的m,最多可以杀多少敌人。

题解:

把敌人按照Bi分为a组和b组,a组的敌人都是没有能量刀的敌人(Bi=0),b组的Bi>0。

枚举1、只用袖口刀杀a组里的人,能杀多少是多少,杀完若m还有剩余,则尝试去杀b组的人,若能杀掉一个防御最低的,用得到的能量刀就能把b组的人全杀掉。

例如数据:

1

5

7 1

7 1

1 0

1 0

1 0

枚举2、仅用袖口刀去杀b组的人,不用能量刀,直到剩余的m值不够用了,在用能量刀接着杀,若能杀完,在用能量刀和袖口刀去杀a组的人

例如数据:

1

6 20

10 2

10 2

100 0

100 0

100 0

100 0

枚举3、用袖口刀杀掉b组防御最低的(杀不掉则回到枚举1),然后用得到的能量刀杀完b组的人,在用袖口刀和能量刀杀a组的人

例如数据:

1

5 5

10 1

4 1

5 2

100 0

1 0

然后比较3种枚举得到的值,得出答案,貌似贪心思想没大用到。。。

#include <iostream>
#include <vector>
#include <algorithm>
#define FOR(a,b) for(int i = (a);i < (b);i ++)
using namespace std;

struct Enemy
{
int Ai,Bi;
};
bool cmp(const Enemy& a,const Enemy& b)
{
return a.Ai < b.Ai;
}
struct Ans
{
int num,cost;
};
bool operator<(const Ans& a,const Ans& b)
{
if(a.num == b.num) return a.cost > b.cost;
return a.num < b.num;
}

vector<Enemy> b;
vector<int> a;

Ans afirst(int m)
{
Ans ans;
ans.cost = 0,ans.num = 0;
for(int i = 0; i < a.size() && m >= a[i];i ++)
{
m -= a[i];
ans.num ++;
ans.cost += a[i];
}
if(!b.empty() && m >= b[0].Ai) ans.num += b.size(),ans.cost += b[0].Ai;
return ans;
}
Ans bfirst(int m,int energy)
{
Ans ans;
ans.num = 0,ans.cost = m;
for(;ans.num < b.size() && m >= b[ans.num].Ai;ans.num ++) m -= b[ans.num].Ai;
ans.cost -= m;

energy -= b.size() - ans.num;
if(energy >= a.size()) ans.num = a.size()+b.size();
else{
ans.num = b.size() + energy;
for(int i = 0;i <= a.size() - energy && a[i] <= m;i ++) ans.num ++,ans.cost += a[i],m -= a[i];
}
return ans;
}
Ans banda(int m,int energy)
{
Ans ans;
ans.num = 0,ans.cost = 0;
ans.cost += b[0].Ai;
m -= ans.cost;
energy -= b.size() -1;
if(energy >= a.size()) ans.num = a.size() + b.size();
else {
ans.num = b.size() + energy;
for(int i = 0;i <= a.size() - energy && a[i] <= m;i ++) ans.num ++,ans.cost += a[i],m -= a[i];
}
return ans;
}
int main()
{
int n,m,num,cost,energy;
Enemy enemy;
Ans ans,ans1,ans2,ans3;
int testcases;
scanf("%d",&testcases);
for(int ca = 1; ca <= testcases; ca ++)
{
a.clear(),b.clear();
num = 0,cost = 0;
energy = 0;
scanf("%d%d",&n,&m);
FOR(0,n)
{
scanf("%d%d",&enemy.Ai,&enemy.Bi);
if(enemy.Bi) b.push_back(enemy),energy += enemy.Bi;
else a.push_back(enemy.Ai);
}
if(!b.empty()) sort(b.begin(),b.end(),cmp);
if(!a.empty()) sort(a.begin(),a.end());

if(a.empty())//每个敌人都有剑
{
if(m >= b[0].Ai) printf("Case %d: %d %d\n",ca,b.size(),b[0].Ai);
else printf("Case %d: 0 0\n",ca);
continue;
}
//枚举1 只用自己的武器在a中杀人
ans1 = afirst(m);
//枚举2 只用自己的武器杀b中的人
ans2 = bfirst(m,energy);
//枚举3 杀一个b中的,用敌人的武器搞死完b,然后搞a
ans3 = banda(m,energy);

ans = ans1 < ans2 ? ans2 : ans1;
ans = ans < ans3 ? ans3 : ans;
printf("Case %d: %d %d\n",ca,ans.num,ans.cost);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐