编程思路
https://www.luogu.com.cn/problem/P8687
用M位二进制数来表示所购买糖果中M种口味的组合情况。//a[1 << M]
a[i]表示糖果的口味组合情况为i时需要购买的最少的糖果包数。
进行预处理,用b[i]保存第i包糖果的口味组合情况。
状态转移方程为a[i|b[j]] = min(a[i|b[j]], a[i] + 1);
#include <iostream>
#include <vector>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#define ll long long
#define PII pair<ll, ll>
using namespace std;
const int N = 1e5 + 7, M = 22, mod = 100000007;
int a[1 << M], b[1 << M];
PII d[N];
int n, m, k;
ll qpow(ll x, ll nn) {
ll result = 1;
while (nn > 0) {
if (nn & 1) {//此处等价于if(power%2==1)
result = result * x ;
}
nn >>= 1;//此处等价于power=power/2
x = x * x;
}
return result;
}
//bool check(ll q) {
// while (q != 0) {
// int w = q % 10;
// if (w == 2 || w == 0 || w == 1 || w == 9) return true;
// q /= 10;
// }
// return false;
//}
void bfs() {
// int hh = 0, tt = 0;
// w[1][1] = 0;
// d[0] = {1, 1};
// while (hh <= tt) {
// int x = d[hh].first, y = d[hh ++].second;
// int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
// for (int i = 0; i < 4; i ++) {
// int xx = x + dx[i], yy = y + dy[i];
// if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && w[xx][yy] == -1 && q[xx][yy] != q[x][y]) {
// d[++ tt] = {xx, yy};
// }
// }
// }
// int ans = 1; // dangqiandianshu
// for (auto vv : q[v]) {
// int cc = dfs(vv);
// int ss = min(ans, m + 1);
// for (int i = ss; i >= 1; i --) {
// for (int j = 1; j <= min(cc, m + 1 - i); j ++) {
// d[v][i + j] = max(d[v][i + j], d[v][i] + d[vv][j]);
// }
// }
//
// ans += cc;
//
// }
// return ans;
}
int c(int cc){
return (cc % n + n) % n;
}
void solve() {
cin >> n >> m >> k;
for (int i = 1;i <= n;i ++){
int h = 0;
for (int i = 1;i <= k;i ++){
int hh;
cin >> hh;
hh --;
h = h|(1 << hh);
}
//a[h] = 1;
b[i] = h;
}
for (int i = 1;i <= 1 << m;i ++) a[i] = 1e9;
a[0] = 0;
for(int i = 0;i < 1 << m;i ++){
for (int j = 1;j <= n;j ++){
a[i|b[j]] = min(a[i|b[j]], a[i] + 1);
}
}
if(a[(1 << m) - 1] == 1e9) a[(1 << m) - 1] = -1;
cout << a[(1 << m) - 1] << endl;
}
// 20 5.57%
//2 2 2 2 2
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
//cin >> t;
while (t --)
solve();
return 0;
}
Orzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz