Description
Given four sets S1,S2,S3,S4.
Each time, a number is selected from four sets to form a re-set S.
Ask the number of S that can be formed.
Solution
Consider such a state:
Currently, the first i elements have been considered and a number has been selected from j sets.
Press the occurrence of the same element in four sets into 20,21,22,23.
Consider pressing 16 cases to 216.
Each time, just enumerate the state to be selected, and transfer it from the subset of the current state to ensure that it will not be multiple-selected from the same set.
#include <bits/stdc++.h>
using namespace std;
class MealPlan{
public:
map<int, long long> mp, dp, dp1;
long long ans;
inline int BitCount(int x) {
int cnt = 0;
for (; x; x -= x & -x) ++cnt;
return cnt;
}
long long countDistinct(vector<int> a, vector<int> b, vector<int> c, vector<int> d) {
for (int i : a) mp[i] |= 1;
for (int i : b) mp[i] |= 2;
for (int i : c) mp[i] |= 4;
for (int i : d) mp[i] |= 8;
dp1[1] = 1;
for (auto i: mp) {
dp = dp1;
int s = i.second;
for (auto j: dp1) {
int x = j.first;
long long res = j.second;
for (int k = 1; k <= 4; k++) {
int y = 0;
for (int t = s; t; t = s & (t - 1)) {
if (BitCount(t) == k) {
for (int p = 0; p < 16; p++)
if (!(p & t) && (x >> p & 1))
y |= 1 << (p | t);
}
}
if (y) dp[y] += res;
}
}
dp1 = dp;
}
for (auto x: dp)
if (x.first >> 15 & 1)
ans += x.second;
return ans;
}
};
MealPlan S;
vector<int> p[4];
int n, x;
int main(void) {
freopen("1.in", "r", stdin);
for (int i = 0; i < 4; i++) {
cin >> n;
for (int j = 0; j < n; j++) {
cin >> x; p[i].push_back(x);
}
}
cout << S.countDistinct(p[0], p[1], p[2], p[3]) << endl;
return 0;
}