# 糖果
糖果店的老板一共有M种口味的糖果出售。为了方便描述,我们将M种口味编号1~M。
小明希望能品尝到所有口味的糖果。遗憾的是老板并不单独出售糖果,而是K颗一包整包出售。
幸好糖果包装上注明了其中K颗糖果的口味,所以小明可以在买之前就知道每包内的糖果口味。
给定包糖果,请你计算小明最少买几包,就可以品尝到所有口味的糖果。
**输入**
第一行包含三个整数N、M 和K。
接下来N 行每行K 这整数$T_1,T_2,…,T_K$,代表一包糖果的口味。
1<=N<=100,1<=M<=20,1<=K<=20,1<=$T_i$<=M。
**输出**
一个整数表示答案。如果小明无法品尝所有口味,输出-1。
**样例输入**
```
6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2
```
**样例输出**
```
2
```
以下错误的一项是?
## aop
### before
```cpp
#include
using namespace std;
```
### after
```cpp
```
## 答案
```cpp
const int N = 105, M = (1 << 20) + 10;
int n, m, k, x, a[N], dp[M];
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> k;
memset(dp, -1, sizeof(dp));
for (int i = 1; i <= n; i++)
{
int s = 0;
for (int j = 1; j <= k; j++)
{
cin >> x;
s |= (1 << (x - 1));
}
dp[s] = 1;
a[i] = s;
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < (1 << m); j++)
{
if (dp[j] == -1)
continue;
int to = j | a[i];
if (dp[to] != -1)
{
dp[to] = min(dp[to], dp[j]);
}
else
{
dp[to] = dp[j] + 1;
}
}
}
printf("%d\n", dp[(1 << m) - 1]);
return 0;
}
```
## 选项
### A
```cpp
int n, m, k;
int dp[1 << 20];
vector a;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> k;
for (int i = 0; i < (1 << m); i++)
{
dp[i] = 9999;
}
for (int i = 0; i < n; i++)
{
int s = 0;
for (int i = 0; i < k; i++)
{
int temp;
cin >> temp;
s |= 1 << (temp - 1);
}
a.push_back(s);
}
dp[0] = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < (1 << m); j++)
{
if (dp[j] == 9999 || (j | a[i]) == j)
continue;
dp[j | a[i]] = min(dp[j] + 1, dp[j | a[i]]);
}
}
if (dp[(1 << m) - 1] == 9999)
cout << -1;
else
cout << dp[(1 << m) - 1];
return 0;
}
```
### B
```cpp
const int maxn = (1 << 20) + 52;
const int inf = 9;
int a[505], n, m, k, dp[2][maxn];
int min(int a, int b, int c)
{
return min(min(a, b), c);
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
int e = 1 << m;
for (int i = 1; i <= n; i++)
{
a[i] = 0;
for (int j = 0; j < k; j++)
{
int temp;
scanf("%d", &temp);
a[i] = a[i] | 1 << (temp - 1);
}
}
for (int i = 0; i < maxn; i++)
{
dp[0][i] = dp[1][i] = inf;
}
dp[0][0] = 0;
bool pos = 1;
for (int i = 1; i <= n; i++, pos = !pos)
{
for (int j = 0; j < e; j++)
{
dp[pos][j] = dp[!pos][j];
}
for (int j = 0; j < e; j++)
{
dp[pos][j | a[i]] = min(dp[pos][j | a[i]], dp[!pos][j | a[i]], dp[!pos][j] + 1);
}
}
if (dp[!pos][e - 1] == inf)
{
printf("-1\n");
}
else
printf("%d\n", dp[!pos][e - 1]);
return 0;
}
```
### C
```cpp
int dp[1 << 20];
int ST[100];
int main()
{
int n, m, k;
cin >> n >> m >> k;
int tot = (1 << m) - 1;
memset(dp, -1, sizeof dp);
for (int i = 0; i < n; i++)
{
int st = 0;
for (int j = 0; j < k; j++)
{
int x;
cin >> x;
st |= (1 << x - 1);
}
dp[st] = 1;
ST[i] = st;
}
for (int i = 0; i <= tot; i++)
{
if (dp[i] != -1)
{
for (int j = 0; j < n; j++)
{
int st = ST[j];
if (dp[i | st] == -1 || dp[i | st] > dp[i] + 1)
dp[i | st] = dp[i] + 1;
}
}
}
cout << dp[tot];
return 0;
}
```