问题描述
糖果店的老板一共有 M种口味的糖果出售。
为了方便描述,我们将 M 种口味编号 1 ∼ M。
小明希望能品尝到所有口味的糖果。
遗憾的是老板并不单独出售糖果,而是 K 颗一包整包出售。
幸好糖果包装上注明了其中 K 颗糖果的口味,所以小明可以在买之前就知道每包内的糖果口味。
给定 N 包糖果,请你计算小明最少买几包,就可以品尝到所有口味的糖果。
输入格式
第一行包含三个整数 N , M , K。
接下来 N 行每行 K 个整数 T1 , T2 , ⋅ ⋅ ⋅ , TK
,代表一包糖果的口味。
输出格式
一个整数表示答案,如果小明无法品尝所有口味,输出 −1。
输入样例
6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2
输出样例
2
数据范围
1 ≤ N ≤ 100 , 1≤N≤100,1≤N≤100,
1 ≤ M , K ≤ 20 , 1≤M,K≤20,1≤M,K≤20,
1 ≤ T i ≤ M 1≤Ti≤M1≤Ti≤M
思路:
背包问题
#include <bits/stdc++.h>
using namespace std;
const int N = 110, M = 1 << 20;
int n, m, k;
int w[N], dp[M];
int main()
{
cin >> n >> m >> k;
for (int i = 0; i < n; i ++)
{
for (int j = 0; j < k; j ++)
{
int x;
cin >> x;
w[i] |= 1 << (x - 1);
}
}
int full = (1 << m) - 1;
for (int i = 0; i < n; i++)
{
for (int j = full; j >= 0; j--)
{
if (dp[j] == 0 && j != 0)
{
continue;
}
int temp = j | w[i];
if (dp[temp] == 0)
{
dp[temp] = dp[j] + 1;
}
else
{
dp[temp] = min(dp[temp], dp[j] + 1);
}
}
}
if (dp[full] == 0)
{
cout << "-1" << endl;
}
else
{
cout << dp[full] << endl;
}
return 0;
}