幼儿园买玩具
题目描述
幼儿园有 n n n 个小朋友,每个小朋友都有自己想玩的玩具。身为幼儿园园长的你决定给幼儿园买一批玩具,由于经费有限,你只能买 m m m 个玩具。已知玩具商店一共卖 k k k 种玩具,编号为 1 , 2 , 3 , … k 1,2,3,…k 1,2,3,…k, 你让每个小朋友把想玩的玩具编号都写在了纸上。你希望满足尽可能多的小朋友的需求,请计算出最多能满足多少个小朋友的玩具需求。
输入描述
第一行,输入三个整数 n , m , k ( 1 ≤ n ≤ 100 , 1 ≤ m ≤ 15 , 1 ≤ k ≤ 15 ) n,m,k(1≤n≤100,1≤m≤15,1≤k≤15) n,m,k(1≤n≤100,1≤m≤15,1≤k≤15),中间用空格分开。接下来 n n n 行,第 i + 1 ( 0 ≤ i < n ) i+1(0≤i<n) i+1(0≤i<n) 行的第一个数字 a i a_i ai 代表第 i i i 个小朋友想玩的玩具数量,接下来有 a i a_i ai 个数字,代表这 a i a_i ai 个玩具的编号。
输出描述
输出一个整数,表示最多能满足多少小朋友的玩具需求。
用例输入 1
5 3 5
2 1 4
0
2 3 1
3 2 3 4
2 4 5
用例输出 1
3
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n, m, k;
cin >> n >> m >> k;
vector<vector<int>> v(n + 1);
for (int i = 1; i <= n; i++)
{
int num; // 该小朋友想玩的玩具数量
cin >> num;
int temp; // 玩具编号
for (int j = 0; j < num; j++)
{
cin >> temp;
v[i].push_back(temp);
}
}
if (m >= k)
{
cout << n;
return 0;
}
int ans = 0;
for (int i = 0; i < (1 << k); ++i) // 二进制枚举所有玩具选择情况
{
int is[16] = {0}; // 记录该二进制状态下选择的玩具编号
int cnt = 0; // 该二进制状态下选择买的玩具的数量
for (int j = 0; j < k; j++)
{
if (i & (1 << j))
is[j + 1] = 1, cnt++;
}
if (cnt == m) // 根据贪心,尽可能多的买玩具能满足更多小朋友的需求,所以只需考虑cnt==m的情况
{
int temp = 0; // 当前选择方案能满足小朋友需求的数量
for (int k = 1; k <= n; k++)
{
bool ok = 1; // 判断是否满足该小朋友的需求
int num = v[k].size();
for (int s = 0; s < num; s++)
{
if (is[v[k][s]] == 0)
{
ok = 0;
break;
}
}
if (ok)
temp++;
}
ans = max(temp, ans); // 维护ans为最大值
}
}
cout << ans;
return 0;
}