一,题目:
有n个空盘子摆放在桌子上,编号依次为1 - n,以及m个条件,编号依次为1 - m。
第i个条件满足时当且仅当第 ai 和第 bi 个盘子中均存在小球。
有k名同学,编号依次为1 - k,第i名同学会选择在编号为 ci 或者 di 的盘子中放一个小球。
请你求出最多有多少个条件能得到满足?
输入格式
第一行两个正整数,分别代表n和m
后面m行,每行两个正整数代表ai和bi。
然后一行一个正整数,代表k.
后面k行,每行两个正整数,分别代表ci和di。
2≤n≤100
1≤m≤100
1≤ai<bi≤n
1≤k≤16
1≤ci<di≤n
输出格式
输出一个整数代表答案
测试样例一
4 4
1 2
1 3
2 4
3 4
3
1 2
1 3
2 3
2
测试样例二
4 4
1 2
1 3
2 4
3 4
4
3 4
1 2
2 4
2 4
4
测试样例三
6 12
2 3
4 6
1 2
4 5
2 6
1 5
4 5
1 3
1 2
2 6
2 3
2 5
5
3 5
1 4
2 6
4 6
5 6
9
二,思路:
这题看时间范围我们就可以大概猜出考察的东西了,时间范围很小一般会用到 dfs,bfs,dp,或者暴力枚举答案等等。这里我们可以直接枚举所有选法方案,那怎么枚举呢?当我们观察到 k<=16,我们可以联想到 2e16(时间复杂度约为1e4级别),那么我们可以直接枚举二进制数。当二进制某位上是一代表我们要选第2个,反之为0,我们选第1个。然后我们根据枚举到的方案去判断,最多有多少条件满足(时间复杂度 100)。
时间复杂度:1e4*100。
三,代码:
#include <iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<stack>
#include<queue>
#include<map>
using namespace std;
#define x first
#define y second
const int N=110,M=1e9+7;
typedef long long ll;
typedef pair<int,int> pii;
pii arr[N],brr[N];
void Solved() {
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b;
cin>>a>>b;
arr[i]={a,b};
}
int k;
cin>>k;
for(int i=0;i<k;i++){
int a,b;
cin>>a>>b;
brr[i]={a,b};
}
int res=0;
//枚举二进制数
for(int i=0;i<1<<k;i++){
//用set来储存我们枚举到的方案,涵盖那些杯子
set<int> s;
for(int j=0;j<k;j++){
if(i>>j&1) s.insert(brr[j].y);
else s.insert(brr[j].x);
}
//判断在该方案下最多有多少条件满足
int cnt=0;
for(int j=1;j<=m;j++){
if(s.count(arr[j].x)!=0&&s.count(arr[j].y)!=0) cnt++;
}
res=max(res,cnt);
}
cout<<res<<endl;
}
int main()
{
int t;
t=1;
while(t--) {
Solved();
}
return 0;
}