1125. Das minimal erforderliche Team (DP-Komprimierung + Pfaddatensätze)

Als Projektmanager erstellen Sie eine Liste der erforderlichen Fähigkeiten  und planen,  einige Personen  req_skillsaus der Kandidatenliste  auszuwählen, um ein „erforderliches Team“ zu bilden (  die Kandidatennummer   enthält eine Liste der Fähigkeiten, die der Kandidat besitzt).peopleipeople[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ähigkeiten  people[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] ; 找前驱
*/

おすすめ

転載: blog.csdn.net/zhi6fui/article/details/129376682