二进制的状态压缩。比如A集合里面有{1,5,7}那么就表示为1010001。B集合有{3,4},二进制表示1100。A|B=1011101。
按照这样的思路 可以用01背包 把所有的组合全部求出来。
#include<string.h> #include<math.h> #include<stdio.h> #include<algorithm> using namespace std; const int maxn = 20; int dp[32800], u[maxn]; int main() { int i; u[0] = 1; for (i = 1; i <= 14; i++) u[i] = 2 * u[i - 1]; int n, m, q, j, s; while (~scanf("%d%d", &n, &m)) { memset(dp, 0, sizeof(dp)); dp[0] = 1; for (i = 1; i <= n; i++) { scanf("%d", &q); int sum = 0; for (j = 0; j<q; j++) { scanf("%d", &s); sum = sum + u[s]; } for (j = 32800 - 5; j >= 0; j--) if (dp[j] == 1) dp[j | sum] = 1; } int ans = 0; for (i = 0; i <= 32800 - 5; i++) if (dp[i] == 1) ans++; printf("%d ", ans - 1); } return 0; }