Als Projektmanager erstellen Sie eine Liste der erforderlichen Fähigkeiten und planen, einige Personen req_skills
aus der Kandidatenliste auszuwählen, um ein „erforderliches Team“ zu bilden ( die Kandidatennummer enthält eine Liste der Fähigkeiten, die der Kandidat besitzt).people
i
people[i]
req_skills
Das sogenannte „notwendige Team“ ist das Team , in dem mindestens ein Mitglied des Teams jede in der Liste der erforderlichen Fähigkeiten aufgeführte Fähigkeit beherrscht. Mitglieder des Teams können durch die Nummern jeder Person vertreten werden:
- Ein Team repräsentiert beispielsweise Kandidaten
team = [0, 1, 3]
mit den Fähigkeitenpeople[0]
,people[1]
und .people[3]
Bitte kehren Sie zu dem kleinsten erforderlichen Team zurück, das durch die Personalnummer angegeben ist. Sie können Antworten in beliebiger Reihenfolge zurückgeben und die Fragendaten garantieren, dass die Antworten vorhanden sind.
Beispiel 1:
Beschreibung: req_skills = ["java", "nodejs", "reactjs"], people = [["java"],["nodejs"],["nodejs", "reactjs"]] Beschreibung: [ 0,2 ]
Beispiel 2:
Antwort: req_skills = ["algorithms","math","java","reactjs","csharp","aws"], people = [["algorithms","math","java"],["algorithms ","math","reactjs"],["java","csharp","aws"],["reactjs","csharp"],["csharp","math"],["aws", "java"]] 输出: [1,2]
Analysieren:
req_skills in binärer Darstellung
arr1 zeichnet die binär beherrschten Fähigkeiten (Karte) der i-ten Person auf.
Binär i = 0 ~ n -1
j sind die Personen, die durch Durchqueren von arr1 gepaart werden
f[i] + 1 < f[i | peo[j]] // f[i] plus die j-te Person
vor[i | peo[j]][0] = i;
pre[i | peo[j][1]] = j ; 1 ist die j-te aufgezeichnete Person
ans[i] = pre[idex][1];
idx = pre[idex][0] ; finde den Vorgänger
Beachten Sie die Initialisierung f[0] = 0;
Wenn der j-te Zustand durch f[i | peoskills[j] ]= min(f[i] + 1,f[i | peoskills[j]) ausgewählt wird
Da der Pfad aufgezeichnet werden muss, ist es einfach, eine Art „Wenn“ zu schreiben
class Solution {
public:
vector<int> smallestSufficientTeam(vector<string>& req_skills, vector<vector<string>>& people) {
int n = req_skills.size();
int f[1<<17];
memset(f,0x3f3f3f,sizeof(f));
vector<int> ans;
map<string,int> m;
int pskill[62]; //记录第 i 个人的 skill
int pro[1<<17][2]; // pro[0] 记录 前驱 pro[1] 记录选的人得位置
for(int i = 0;i < req_skills.size();i++){
m[req_skills[i]] = i;
}
f[0] = 0; // 初始化
for(int i = 0;i < people.size();i++){
int cur = 0;
for(int j = 0;j < people[i].size();j++){
cur |= 1<<m[people[i][j]]; // 这里不能用 + 如果由重复 的 由被多加
}
pskill[i] = cur;
}
for(int i = 0;i < 1<<n;i++){
for(int j = 0;j < people.size();j++){
if(f[i] + 1 < f[i | pskill[j]]){
f[i | pskill[j]] = f[i] + 1;
pro[i | pskill[j]][0] = i; // 是由 第 i 个状态转化而来得
pro[i | pskill[j]][1] = j; // 转化而来得 是 在 第 i 个状态上加 第 j 个人
}
}
}
cout << f[(1<<n)-1];
for(int i = (1<<n) - 1 ;i > 0;){
ans.push_back(pro[i][1]);
i = pro[i][0];
}
return ans;
}
};
/*
req_skills 用二进制表示
arr1 记录第 i 个人得二进制掌握得skill( map)
二进制 i = 0 ~ n -1
j为遍历arr1 配对得 people
f[i] + 1 < f[i | peo[j]] // f[i] 加上 第 j个人
pre[i | peo[j]][0] = i;
pre[i | peo[j][1]] = j ; 1 为记录得第 j 个人
ans[i] = pre[idex][1];
idx = pre[idex][0] ; 找前驱
*/