1.题目描述
世界局势风云变幻,你想办一件大事。办事自然要有人参与,你能从几个人里面挑选一部分人共襄盛举。
要办这件事,一共涉及k方面的能力,例如游说他人的能力、玩游戏的能力、睡觉的能力。每位人士都会具备某一些能力,例如机器猫就可能擅长睡觉、擅长玩游戏,而不擅长游说他人。
你的计划很宏伟,因此你希望团队拥有很全面的能力。不幸的是,如果团队中有偶数个人拥有同一类能力,那么他们就会分成两派,争执不下,导致整个团队丧失这方面的能力。相应地,如果这项能力只有奇数个人拥有,那么他们总能形成一个多数派,帮团队去做这方面的工作。
需要注意的是,团队拥有的每一项能力,对计划的成功率的贡献是不一样的。第一项能力最重要,它的权重是 26-1:第二项能力的权重是 2.-2:依次类推。第 k 项能力最不重要,权重只有 1。
计划的成功率得分,即是团队拥有的所有能力对应的权重之和。
你希望计划成功率最大。因此,你需要选出合适的人士,来参与到你的宏图伟业中。
2.输入格式
第一行,两个正整数 n,k。分别表示供你挑选的人的数量,以及能力的种类数。接下来几行,每行表示每个人拥有的能力。这一行首先有一个整数c,表示该人士拥有多少种能力;接下来是 c个1,k 之间的正整数,表示该人士拥有哪些能力。
3.输入输出样例
输入1:
5 5
1 1
1 2
1 3
1 4
1 5
输出1:
31
输入2:
3 5
3 1 2 3
4 2 3 4 5
2 3 4
输出2:
28
输入3:
3 5
2 1 2
3 5 3 2
3 4 2 5
输出3:
30
输入4:
21 60
0
0
3 60 27 48
0
1 48
2 52 14
2 4 31
0
0
2 28 43
2 6 31
0
1 7
3 45 6 48
0
1 51
0
2 28 20
2 37 51
1 8
53 59 39 29 23 53 27 13 16 44 34 38 24 9 32 58 54 31 1 7 45 3 30 36 17 48 42 22 18 21 6 11 25 33 37 52 10 60 49 57 2 28 8 14 5 47 4 41 35 43 50 46 26 12
输出4:
1152884121210322895
4.说明/提示
1.样例解释
第一组样例,共5个人,每个人拥有的能力不一样。最终选择的结果是让这5个人都参与计划,得分16+8+4+2+1=31。
第二组样例,我们选择只让1参与。那么团队具有能力 1.2.3,得分16+8+4= 28。
第三组样例,我们让 1,2,3 参与。由于团队中有偶数个成员拥有能力5,故团队并不拥有能力5。奇数个成员拥有能力 2,故团队拥有能力 2。最终,团队具有能力 1,2,3,4。得分 16+8+4+2= 30。
2.数据规模与约定
对于 100% 的数据,有 n < 21,k < 60。
4.代码:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
// 每个人的能力集合
vector<vector<int>> abilities(n);
for (int i = 0; i < n; ++i) {
int c;
cin >> c;
abilities[i].resize(c);
for (int j = 0; j < c; ++j) {
cin >> abilities[i][j];
}
}
long long maxScore = 0;
// 遍历所有组合
for (int mask = 0; mask < (1 << n); ++mask) {
vector<int> count(k + 1, 0); // 用于统计每种能力的拥有人数
for (int i = 0; i < n; ++i) {
if (mask & (1 << i)) { // 如果选择了第i个人
for (int ab : abilities[i]) {
count[ab]++;
}
}
}
long long score = 0;
// 计算得分
for (int i = 1; i <= k; ++i) {
if (count[i] % 2 == 1) { // 奇数
score += (1LL << (k - i)); // 2^(k-i)
}
}
maxScore = max(maxScore, score);
}
cout << maxScore << endl;
return 0;
}