这道题属于是最小覆盖问题,属于NP-hard问题,可以通过贪心算法计算近似解。
但要求出完美解,有以下两种常用的思路。
1.状态压缩下的动态规划
状态实在是太多了,所以要用一个数的比特位来代替。
代码:
class Solution(object):
def smallestSufficientTeam(self, req_skills, people):
"""
:type req_skills: List[str]
:type people: List[List[str]]
:rtype: List[int]
"""
#对数据进行编码
map_dict = {name: (1 << offset) for offset, name in enumerate(req_skills)}
group = [0 for i in range(len(people))]
#
for idx, skills in enumerate(people):
skill_num = 0
for k in skills:
# print(k)
skill_num += map_dict[k]
group[idx] = skill_num
# print(group)
print(sum(map_dict.values()))
dp = [[] for i in range(sum(map_dict.values()) + 1)]
for val in range(len(dp)):
if val > 0 and dp[val] == []:
continue
for person, skill in enumerate(group):
if skill == 0:
continue
combine = skill | val
if len(dp[combine]) > len(dp[val]) + 1 or not dp[combine]:
dp[combine] = dp[val] + [person]
return dp[-1]
2.DFS+记忆化搜索
对于每个人员来说,只有选或不选两种情况,于是我们可以考虑记忆化搜索。其实动态规划方法也是在做一种记忆化的搜索。
代码略。