Title Link: Https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem &problem=5158
Surface:
Pdf
Main topic:
Both sides, our N army, enemy M army, each army two attribute values, health value and attack damage. War between the two armies, their own health value minus the opponent's attack. If the remaining health value is less than or equal to 0, the sacrifice. If our army can destroy the enemy, if we can, the maximum number of troops survived, if not, output-1.
Solving:
When doing, how can not clear the idea, because to combine data structure considerations, always feel unable to find the right data structure. Referring to this blog, the general idea is this, the first task is to eliminate all the enemy, the secondary task is to preserve more of their own troops. Our troops are sorted by attack first, and the enemy troops are sorted by their health. Using Multiset to maintain the health of our troops, as long as they join the army in Multiset, their attack is enough to destroy the enemy's current and future teams. For an army of the enemy, find the minimum health that we can destroy and not destroy, and if not, sacrifice the smallest value in Multiset.
Summarize:
For the greedy problem, it is necessary to clarify the greedy strategy and clarify the thinking to help solve problems.
Add:
In addition, the use of multiset also need to be careful, erase operation, corresponding to two parameters, if it is a value, then delete all the value of that number, if it is an iterator, then only delete the value of the iterator. See this blog.
Code:
#include <iostream> #include <algorithm> #include <set> #include <cstdio> #include <cstring&
Gt
using namespace Std; struct Troop {//damage, health value int harm,life;}
US[100010],EN[100010]; Sort by attack bool Cmp1 (Troop A,troop b) {return a.harm>b.harm;}//Sort by health bool CMP2 (Troop A,troop b) {return a.life>
B.life;
} int main () {int t,p=0,cnt,n,m;
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<n;j++) scanf ("%d%d", &us[j].harm,&us[j].life);
for (int j=0;j<m;j++) scanf ("%d%d", &en[j].harm,&en[j].life);
If our number of troops is less than the enemy, direct output-1 if (n<m) {printf (" -1\n");
Continue
}//We rank sort (us,us+n,cmp1) by attack height;
The enemy sorts by their health sort (EN,EN+M,CMP2);
Storage of our attack multiset <int> defense;
P Our subscript, cnt we sacrificed the quantity p=cnt=0;
Flag=true; for (int j=0;j<m;j++) {for (int k=p;k<n;k++) {//The health of the army that we can destroy the enemy forces is added to the multiset if (US[K].harm>=en[j].life) {Defense.insert (us[k].life);
p++;
} else break;
}//If our remaining troops cannot destroy enemy troops, break, output-1 if (Defense.empty ()) {flag=false;
Break
} else {//Can not lose the army, then use our health value is higher than the enemy to eliminate//if the army must be lost, the loss of the current health of the lowest multiset <int>:: iterator it;
It=defense.upper_bound (En[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; }