Strange Birthday Party
看题不仔细,做题两行泪。
一开始以为给每个朋友的礼物是小于等于手上数字的商品序号或等量钱。虽然每件商品都只有一件,但都可选的价值最小的商品的钱就行。看案例解释没看懂,也没回去看题。
正确题意:给每个人小于等于手上数字序号的任意一件商品(每个商品用一次),或者给手上序号对应商品的钱。
做题思路:商品价值已经是按非降序排列。朋友手上的数字没有规律,将这个数组按非升序排列,朋友对于每一件商品,如果有一个朋友的数字≥该商品的序号并且还没给他送礼物,那么给他送这件商品比送钱更优。因此要送哪些商品是已经确定的。当钱送的最少时,用总花费就最少。
商品价值按升序排列,因此朋友的数字越小,送的钱越少。
将朋友的数字按降序排列,先把所有应该送的小价值商品送完,剩下的是朋友全送钱,此时送的钱最少。即总花费最少。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 300010;
int f[N], p[N];
bool st[N];
int main() {
int n, m, t;
scanf("%d", &t);
while (t --) {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++) scanf("%d", &f[i]);
for (int i = 1; i <= m; i ++) scanf("%d", &p[i]);
long long ans = 0, ch = 0;
sort(f + 1, f + n + 1, greater<int>());
for (int i = 1; i <= n; i ++) {
if (++ ch < m && p[f[i]] >= p[ch])ans += p[ch];
else ans += p[f[i]];
}
printf("%lld\n", ans);
}
return 0;
}