[蓝桥杯 2019 省 A] 糖果
题目描述
糖果店的老板一共有 M M M 种口味的糖果出售。为了方便描述,我们将 M M M 种口味编号 1 1 1 ∼ M M M。
小明希望能品尝到所有口味的糖果。遗憾的是老板并不单独出售糖果,而是 K K K 颗一包整包出售。
幸好糖果包装上注明了其中 K K K 颗糖果的口味,所以小明可以在买之前就知道每包内的糖果口味。
给定 N N N 包糖果,请你计算小明最少买几包,就可以品尝到所有口味的糖果。
输入格式
第一行包含三个整数 N N N、 M M M 和 K K K。
接下来 N N N 行每行 K K K 这整数 T 1 , T 2 , ⋯ , T K T_1,T_2, \cdots ,T_K T1,T2,⋯,TK,代表一包糖果的口味。
输出格式
一个整数表示答案。如果小明无法品尝所有口味,输出 − 1 -1 −1。
样例 #1
样例输入 #1
6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2
样例输出 #1
2
提示
对于 30 % 30\% 30% 的评测用例, 1 ≤ N ≤ 20 1 \le N \le 20 1≤N≤20。
对于所有评测样例, 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100, 1 ≤ M ≤ 20 1 \le M \le 20 1≤M≤20, 1 ≤ K ≤ 20 1 \le K \le 20 1≤K≤20, 1 ≤ T i ≤ M 1 \le T_i \le M 1≤Ti≤M。
蓝桥杯 2019 年省赛 A 组 I 题。
AC代码:
#include<map>
#include<set>
#include<stack>
#include<cmath>
#include<queue>
#include<string>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<numeric>
#include<iomanip>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int, int>PII;
const int N=3e5+10;
const int MOD=1e9 + 7;
const int INF=0X3F3F3F3F;
const int dx[]={-1,1,0,0,-1,-1,+1,+1};
const int dy[]={0,0,-1,1,-1,+1,-1,+1};
const int M = 1 << 20 ;
int n, m, k;
int w[M], dis[M];
int main()
{
cin >> n >> m >> k;
for(int i = 1; i <= n; i ++)
{
for(int j = 0; j < k; j ++)
{
int x;
cin >> x;
w[i] |= 1 << (x - 1);
}
}//状压dp
queue<int>q;
memset(dis, -1, sizeof dis);
q.push(0);
dis[0] = 0;
while(q.size()){
int pre = q.front(); q.pop();
for(int i = 1; i <= n; i ++)
{
int now = pre | w[i];
if(dis[now] != -1) continue;
q.push(now);
dis[now] = dis[pre] + 1;
}
}
cout << dis[(1 << m) - 1] << endl;
return 0;
}