CF1471-C. Strange Birthday Party

CF1471-C. Strange Birthday Party

题意:

你要举办一场生日派对。派对有\(n\)个人,每个人都有一个数字\(k_i\)。超市有\(m\)件礼物,购买每件礼物需要花费\(\$c_j(c_1<c_2<...<c_m)\),且每个礼物只有一件。你要给这\(n\)个人发东西,对于第\(i\)个人,你有两种选择:

  1. 给第\(i\)个人发礼物,那么给这个人的礼物要求\(j<=k_i\),即礼物的编号不能超过这个人的数字\(k_i\);

  2. 直接给这个人\(\$c_{k_i}\).

现在要你求出最小的花费。


思路:

按花费从小到大依次分配礼物。假设现在要分配的礼物的编号是\(cur\),利用贪心的思想,当\(cur<=k_i\)时,依次将花费最小的礼物分给\(k_i\)最大的人;当\(cur>k_i\)时,直接给这位朋友\(\$c_{k_i}\)

原因如下:当\(cur<=k_i\)时,有\(c_{cur}<=c_{k_i}\);当\(cur>k_i\)时,有\(c_{k_i}<c_{cur}\),每次都取两者中较小的。


AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>

typedef long long ll;

const int Maxn = 300005;

int a[Maxn], b[Maxn];

void solve() {
	int n, m;
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", a + i);
	}
	for (int i = 1; i <= m; i++) {
		scanf("%d", b + i);
	}
	std::sort(a + 1, a + n + 1);
	ll ans = 0;
	int cur = 1;
	for (int i = n; i > 0; i--) {
		if (a[i] > cur) {
			ans += b[cur++];
		} else {
			ans += b[a[i]];
		}
	}
	printf("%lld\n", ans);
}

int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		solve();
	}

	return 0;
}

posted @ 2021-01-24 11:51  牟翔宇  阅读(101)  评论(0编辑  收藏  举报