# 糖果

糖果店的老板一共有M种口味的糖果出售。为了方便描述，我们将M种口味编号1~M。  

小明希望能品尝到所有口味的糖果。遗憾的是老板并不单独出售糖果，而是K颗一包整包出售。  

幸好糖果包装上注明了其中K颗糖果的口味，所以小明可以在买之前就知道每包内的糖果口味。  

给定包糖果，请你计算小明最少买几包，就可以品尝到所有口味的糖果。  

**输入**

第一行包含三个整数N、M 和K。  

接下来N 行每行K 这整数T<sub>1</sub>,T<sub>2</sub>,…,T<sub>K</sub>，代表一包糖果的口味。  

1<=N<=100，1<=M<=20，1<=K<=20，1<=T<sub>i</sub><=M。  

**输出**

一个整数表示答案。如果小明无法品尝所有口味，输出-1。


**样例输入**

```
6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2
```

**样例输出**

```
2
```

以下<span style="color:red">错误</span>的一项是？

## aop

### before

```c
#include <bits/stdc++.h>
using namespace std;
```

### after

```c

```

## 答案

```c
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

```c
int n, m, k;
int dp[1 << 20];
vector<int> 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

```c
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

```c
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;
}
```
