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

HDU4415（枚举，贪心）

例如数据：

1
5
7 1
7 1
1 0
1 0
1 0

1
6 20
10 2
10 2
100 0
100 0
100 0
100 0

1
5 5
10 1
4 1
5 2
100 0
1 0

#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);
}
}