[uva_la7146 Defeat the Enemy(2014 shanghai onsite)]贪心
题意:我方n个军队和敌方m个军队进行一对一的对战,每个军队都有一个攻击力和防御力,只要攻击力不小于对方就可以将对方摧毁。问在能完全摧毁敌方的基础上最多能有多少军队不被摧毁。
思路:按防御力从大到小考虑敌方的军队由我们哪只军队去摧毁,对每个敌方军队,维护我方军队可以摧毁它的集合,用S表示,从大到小考虑保证了S更容易维护,只需要记录防御力就够了,不需要大量的删除操作。我们需要选择S中防御力大于当前敌方军队且最小的军队,那么这个军队是可以摧毁敌方军队而自己不被摧毁的。如果这样的军队不存在,那么直接用S中防御力最小的去和敌方军队同归于尽,因为这样做到了自己损失最小。如果中间某个时刻S为空了,则说明我方派不出摧毁当前敌方军队的军队了。
(忠告:维护集合时先想想是用set呢还是multiset,否则又该怀疑数据有问题了。。。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#pragma comment(linker, "/STACK:10240000") #include <bits/stdc++.h> using namespace std; #define X first #define Y second #define pb push_back #define mp make_pair #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) typedef long long ll; typedef pair<int, int> pii; #ifndef ONLINE_JUDGE namespace Debug { void print(){cout<<endl;}template<typename T> void print(const T t){cout<<t<<endl;}template<typename F,typename...R> void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T> void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;} } #endif // ONLINE_JUDGE template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);} template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);} /* -------------------------------------------------------------------------------- */ const int maxn = 1e5 + 7; multiset<int> s; int n, m; pii a[maxn], b[maxn]; void work() { int ans = n - m; s.clear(); int now = n - 1; for (int i = m - 1; i >= 0; i --) { while (now >= 0 && a[now].X >= b[i].X) s.insert(a[now --].Y); if (!s.size()) { puts("-1"); return ; } multiset<int>::iterator iter = s.upper_bound(b[i].Y); if (iter == s.end()) s.erase(s.begin()); else { ans ++; s.erase(iter); } } printf("%d\n", ans); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // ONLINE_JUDGE int T, cas = 0; cin >> T; while (T --) { printf("Case #%d: ", ++ cas); cin >> n >> m; for (int i = 0; i < n; i ++) { scanf("%d%d", &a[i].X, &a[i].Y); } for (int i = 0; i < m; i ++) { scanf("%d%d", &b[i].Y, &b[i].X); } if (n < m) puts("-1"); else { sort(a, a + n); sort(b, b + m); work(); } } return 0; } |