1125. El equipo mínimo necesario (compresión dp + registros de ruta)

Como director del proyecto, usted planifica una lista de habilidades requeridas  y planea  seleccionar algunas personas  req_skillsde la lista de candidatos  para formar un "equipo requerido" (  el candidato  numerado  contiene una lista de habilidades que posee el candidato).peopleipeople[i]

req_skills El llamado "equipo necesario" es aquel equipo en el que al menos un miembro del equipo ha dominado cada habilidad enumerada en la lista de habilidades requeridas  . Los miembros del equipo pueden estar representados por el número de cada persona:

  • Por ejemplo, un equipo  representa  candidatos team = [0, 1, 3] con habilidades de  people[0], people[1]y  .people[3]

Por favor regrese  al  equipo más pequeño necesario indicado por el número de personal. Puede devolver respuestas en  cualquier orden  y los datos de la pregunta garantizan que las respuestas existen.

Ejemplo 1:

Descripción: req_skills = ["java","nodejs","reactjs"], people = [["java"],["nodejs"],["nodejs","reactjs"]]输出: [
 0,2 ]

Ejemplo 2:

Nota: req_skills = ["algoritmos","matemáticas","java","reactjs","csharp","aws"], people = [["algoritmos","matemáticas","java"],["algoritmos ","math","reactjs"],["java","csharp","aws"],["reactjs","csharp"],["csharp","math"],["aws", "java"]]
输出: [1,2]

Analizar gramaticalmente:

    req_skills en representación binaria

    arr1 registra la habilidad binaria dominada por la i-ésima persona (mapa)

    Binario i = 0 ~ n -1

    j son las personas emparejadas al atravesar arr1

     f[i] + 1 < f[i | peo[j]] // f[i] más la j-ésima persona

    pre[yo | personas[j]][0] = i;

    pre[i | peo[j][1]] = j ; 1 es la j-ésima persona registrada

    respuesta[i] = pre[idex][1];

    idx = pre[idex][0] ; encuentra el predecesor

Tenga en cuenta la inicialización f[0] = 0;

Cuando el estado j es seleccionado por f[i | peoskills[j] ]= min(f[i] + 1,f[i | peoskills[j])

Debido a que es necesario registrar la ruta, es fácil escribir una especie de si 

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] ; 找前驱
*/

Supongo que te gusta

Origin blog.csdn.net/zhi6fui/article/details/129376682
Recomendado
Clasificación