C - Anadi and Domino
题意
给定21张牌,每张牌的两端有两个数字,数字 1 ≤ a , b ≤ 6 1\leq a,b\leq 6 1≤a,b≤6
给定一个无向图,选择一些牌放在条边上,要求牌朝向图上的点的那一端,如果已经有牌指向这个点,那么这个点所对的所有牌的对应的一端必须是相同的数字
问最多能放多少张牌
题解
最多有7个点,21条边,21牌
我们可以把每个边指向的那个点的编号设为牌的权,枚举看看合法的情况下最多的牌有多少张
Code
int T;
int n, m;
int g[100][100];
int col[100];
bool st[100][100];
ll ans;
void dfs(int x){
if(x == n + 1){
memset(st, 0, sizeof(st));
ll cnt = 0;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
if(i == j)
continue;
if(!g[i][j])
continue;
st[col[i]][col[j]] = 1;
st[col[j]][col[i]] = 1;
}
}
for (int i = 1; i <= 6; i++){
for (int j = i; j <= 6; j++){
if(st[i][j])
cnt++;
}
}
ans = max(ans, cnt);
return;
}
for (int i = 1; i <= 6; i++){
col[x] = i;
dfs(x + 1);
}
}
void solve(){
cin >> n >> m;
for (int i = 1; i <= m; i++){
int a, b;
cin >> a >> b;
g[a][b] = 1;
g[b][a] = 1;
}
dfs(1);
cout << ans << endl;
}
D - Marcin and Training Camp
题意
给定一批学生的能力值和权值,学生的能力值用2进制表示,如果人a的某一位上为1,另一个人b的这一位上为0,那么a瞧不起b,允许两人互相瞧不起
现在要组建一个人数至少2人的团队,要求里面的人不会瞧不起除他自己以外的所有人,问这个团队的最大权值是多少
题解
首先我们考虑,要让两个人互相不会瞧不起,要么就是对应位上a为0,b也为0,要不就是a上为1,b上也为1
那么就是要求得有至少两人的能力值相等才能组成一个团队
那么相同能力的人的集合就是一个初步的团队
那么其他人如果能加入到这个团队中去,必须要求这个人不会看不起这个组里的其他所有人,也就是存在一个人使得这个人看得起
等价于这个人的会的算法存在团队里的某一个人他都会,即 a ∣ b = b a|b=b a∣b=b,b为集合里的人
Code
#define a first
#define b second
using PII = pair<ll, ll>;
int T;
int n;
PII c[N];
bool st[N];
set<ll> s;
void solve(){
cin >> n;
for (int i = 1; i <= n; i++){
cin >> c[i].a;
}
for (int j = 1; j <= n; j++){
cin >> c[j].b;
}
sort(c + 1, c + 1 + n);
ll ans = 0;
for (int i = 1; i <= n; i++){
ll cnt = 1;
while(i < n && c[i].a == c[i + 1].a){
cnt++;
ans += c[i].b;
st[i] = 1;
s.insert(c[i].a);
i++;
}
if(cnt > 1){
ans += c[i].b;
s.insert(c[i].a);
st[i] = 1;
}
}
for (int i = 1; i <= n; i++){
if(!st[i]){
for(auto j : s){
if((c[i].a | j) == j){
ans += c[i].b;
break;
}
}
}
}
cout << ans << endl;
}