题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5281
bc:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=608&pid=1002
Senior's Gun
Accepts: 235
Submissions: 977
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
学姐姐是一个酷酷的枪手。
她常常会随身携带nn把枪,每把枪有一个攻击力a[i]a[i]。
有一天她遇到了mm只怪兽,每只怪兽有一个防御力b[j]b[j]。现在她决定用手中的枪消灭这些怪兽。
学姐姐可以用第ii把枪消灭第jj只怪兽当且仅当b[j]leq a[i]b[j]≤a[i],同时她会获得a[i]-b[j]a[i]−b[j]的分数。
每把枪至多只能使用一次,怪兽死后也不会复活。现在学姐姐想知道她最多能得到多少分(她可以不用消灭所有的怪兽)。
输入描述
第一行包含一个整数TT,表示测试数据组数。
对于每组测试数据:
第一行包含两个整数n,mn,m,表示枪的数量和怪兽的数量。
第二行包含nn个整数a[i]a[i],表示枪的攻击力。
第三行包含mm个整数b[j]b[j],表示怪兽的防御力。
1leq n, mleq 1000001≤n,m≤100000, -10^9 leq a[i], b[j]leq 10^9−109≤a[i],b[j]≤109。
输出描述
对于每组测试数据,输出一个整数表示对应的答案。
输入样例
1
2 2
2 3
2 2
输出样例
1
题解:
这一道题掌握最优解充要条件就可以写出来了。
1:最优解一定是最高攻击力的k把枪去砍防御力最弱的k个怪。
证明:如果有一把枪不是最高攻击力里面的,你就可以用最高k把里面的去替换它,这样会得到更优解。
2:k个怪里面防御力最高的一定比k把枪里面攻击力最小的还要小。(也就是最优解中,任意一把枪能砍任意一个怪,这样就不需要管用哪把枪砍哪个怪了)
证明:否则,怪最高防御力就会大于最低攻击力的枪,这样丢掉这把枪和这个怪,得到的解会更优。
所以一直用当前攻击力最高的枪去砍防御力最低的怪直到不能砍为止,得到的解就是最优解了。
代码:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn = 101010; typedef long long LL; int n, m; int a[maxn], b[maxn]; int main() { int tc; scanf("%d", &tc); while (tc--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", a + i); for (int i = 0; i < m; i++) scanf("%d", b + i); sort(a, a + n); sort(b, b + m); LL ans = 0; for (int i = n - 1, j = 0; i >= 0 && j<m&&a[i]>b[j]; i--, j++) { ans += a[i] - b[j]; } printf("%lld ", ans); } return 0; }