赞
踩
一个“纯职业小组”定义为由 3 名同职业的士兵组成的队伍。
遍历所有职业计算出最大队伍数量。
res = 0
for i in range(n):
res += b[i] // 3
if res < k:
print(-1)
continue
假设有:
职业 | a | b | c | d |
---|---|---|---|---|
数量 | 1 | 2 | 3 | 4 |
假设 k = 1 k = 1 k=1,如果想要多选一些人,那就是不希望太快凑出队伍,可以先选 1 1 1 个 a a a, 2 2 2 个 b b b, 2 2 2 个 c c c, 2 2 2 个 d d d(选两个是因为如果三个,就凑成一支队伍了)。
这时:
职业 | a | b | c | d |
---|---|---|---|---|
数量 | 0 | 0 | 1 | 2 |
已选 7 7 7 人,接下来再选一个 c c c 或者 d d d,即可凑成一支队伍。
根据上述分析,以及贪心思想,我们可以先将所有队伍取出 2 2 2 个人,若队伍为 1 1 1 人则取 1 1 1 人,此时不构成一支队伍。
好的,接下来我们要如何做?
先选出所有的 < 3 <3 <3 的人头,这些都是白送的 /doge。
很显然,根据贪心的策略,有 3 3 3 选 3 3 3,无 3 3 3 选 2 2 2,无 2 2 2 选 1 1 1。
那么如何处理 k = 1 k = 1 k=1 的情况,我们可以直接将读入的 k k k 直接 k − = 1 k -= 1 k−=1, r e s + = 1 res += 1 res+=1,因为,如果有解的情况下,我们刚开始白嫖的时候,一定会白嫖到最少一种职业有 2 2 2 个人,那么再选一个就会导致直接构成一支队伍,但是 r e s res res 只有 + 1 +1 +1,和前面的贪心分析不合,故可以特殊处理。
import sys sys.setrecursionlimit(1000000) input = lambda:sys.stdin.readline().strip() T = int(input()) for _ in range(T): n, k = map(int, input().split()) h = {} for i in range(n): a, b = map(int, input().split()) if a not in h: h[a] = 0 h[a] += b b = [] for x in h: b.append(h[x]) n = len(b) cnt = 0 res = 0 for i in range(n): cnt += b[i] // 3 u = min(b[i], 2) b[i] -= u res += u if cnt < k: print(-1) continue c1, c2, c3 = 0, 0, 0 for x in b: c3 += x // 3 x %= 3 if x == 1: c1 += 1 elif x == 2: c2 += 1 k -= 1 res += 1 v = min(k, c3) k -= v c3 -= v res += v * 3 v = min(k, c2) k -= v c2 -= v res += v * 2 v = min(k, c1) k -= v c1 -= v res += v * 1 print(res)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。