一言不合就暴力枚举……比赛的时候看N<=15+一时半会儿想不到好方法的时候应该就可以开始暴力了
(这种判断真话假话的题好像属于NP完全问题,目前还没有非指数级的办法,只能用随机算法把底数变小)
(新手村的菜鸡还是暴力枚举吧Q-Q)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
int numz[16];//存每个人说了几句话
int n;
int ans;
vector<pair<int,int>> kotoba[16];//存每个人说的每句话
int main(){
cin>>n;
//读入
for(int i=1;i<=n;i++){
cin>>numz[i];
for(int j=1;j<=numz[i];j++){
int l,r;
cin>>l>>r;
kotoba[i].push_back({l,r});
}
}
//位运算枚举每一种状况,最多2^15次方种
for(int i=0;i<1<<n;i++){
int cnt=0;
int flag=false;
for(int j=0;j<n;j++){
if(i>>j &1 ==1){
cnt++;
for(int k=0;k<numz[j+1];k++){
auto p=kotoba[j+1][k];
int l=p.first,r=p.second;
if((i>>(l-1)&1) != r) {//说的话和真实情况有矛盾,这种状况就不行
flag=true;
break;
}
}
}
if(flag==true) break;
}
if(flag==false) ans=max(ans,cnt);//取说真话的人最多者
}
cout<<ans<<endl;
return 0;
}