PROBLEM LINK:
Author: Constantine Sokol
Tester: Mahbubul Hasan
Editorialist: Jingbo Shang
DIFFICULTY:
Easy
PREREQUISITES:
Search
PROBLEM:
Given N objects and M weighted subsets of them, find a combination of subsets, such that all objects are covered at most once and the sum of the weights are maximized.
Some test cases are added in the practice room.
EXPLANATION:
Although N is large, M is quite small such that 2^M is tolerant. Therefore, we first need to construct the conflicts between different subsets. Two subsets are called conflict if and only if they shares a common object. To get this conflicts table, on each object, we can restore the IDs of subsets who contain the object. And then, mark they are conflicted with each other. This step takes O(N * M^2). Moreover, we can reduce the time complexity using the binary expression as following.
conflict[li] = 0;
[/li] For i = 1 to N do
int mask = 0;
For ID in IDs[i] do
mask |= 1 << ID;
end
For ID in IDs[i] do
conflict[ID] |= mask;
end
end
where, conflict[i] >> j & 1 stands for whether the i-th and j-th subsets are conflicted with each other. This code needs only O(NM) time.
And then, a simple DFS search can be applied to find the maximum weighted valid choice, like following:
int DFS(int i, int mask, int sum)
if (i == M) {
return sum;
}
int ret = DFS(i + 1, mask, sum); // don't select the i-th subset
if (mask >> i & 1) {
// conflicted, can't be chosen.
} else {
// try to select the i-th subset
ret = max( ret, DFS(i + 1, mask | conflict[i], sum + weight[i]);
}
return ret;
end
This procedure takes O(2^M) time. Therefore, the overall time complexity is O(NM+2^M).
AUTHOR’S AND TESTER’S SOLUTIONS:
Author’s solution can be found here.
Tester’s solution can be found here.