Sunday, July 16th

Today's problem is to create a team of the smallest size with all the required skills



Given a list of required skills, and a list of people each with their own skillset, find the smallest possible group of people such that all the required skills are met

First, we convert the skills from strings to integers using a hash map

    int n = people.size(), m = req_skills.size();
unordered_map<string, int> skillsMap;
for (int i = 0; i < m; i++) {
skillsMap[req_skills[i]] = i;
}

Next, we formulate the problem using bitmasks.  We can represent a set using bits, where a 1 denotes the skill has been included, or 0 for absent.  Moreover, we can represent each individual using a bitmask where a 1 denotes a skill they have.  Thus the problem is to find a collection of people so the skills bitmask is all 1's. 

Here we store the skills of individuals using a bitmask

    vector<int> personSkills(n);
for (int i = 0; i < n; i++) {
for (int i=0; I<people.size(); i++) {
            string skill = people[i];
personSkills[i] |= 1 << skillsMap[skill];
}
}

Since the problem asks to find the minimum of something, and because the decision on whether or not to include someone depends on earlier decisions, this problem may be suited for dynamic programming.  We will pursue bottom-up dynamic programming.

We initialize a 1-d dp array of size 2^m and initialize it with values of 2^n -1

Then for each skill, we iterate from 0 to n-1.  We set the smallerSkillsMask to the set difference of skillsMask and skillsMaskOfPerson[i].  If smallerSkillsMask doesn't equal skillsMask, we set the peopleMask to dp[smallerSkilssMask] OR'ed with 2^i.  This is a new team added with the current person.  Then we update the dp array with peopleMask if it has fewer bits set 

        vector<long long> dp(1 << m, (1LL << n) - 1);
dp[0] = 0;
for (int skillsMask = 1; skillsMask < (1 << m); skillsMask++) {
for (int i = 0; i < n; i++) {
int smallerSkillsMask = skillsMask & ~skillsMaskOfPerson[i];
if (smallerSkillsMask != skillsMask) {
long long peopleMask = dp[smallerSkillsMask] | (1LL << i);
if ( count_set_bits(peopleMask) < count_set_bits(dp[skillsMask])) {
dp[skillsMask] = peopleMask;
}
}
}
}

Once we have our answer, we convert it back to individuals so we have our solution

    long long answerMask = dp[(1 << m) - 1];
vector<int> ans;
for (int i = 0; i < n; i++) {
if ((answerMask >> i) & 1) {
ans.push_back(i);
}
}
return ans;

Based off shared solutions

Comments

Popular posts from this blog

Wednesday, September 20th

Monday, September 11th

Tuesday, September 19th