题目大意

2n2n 个人,每第 ii 个人与第 jj 个人一组会产生 ai,ja_{i,j} 的价值,求所有价值异或的最大值,其中 1n81\le n \le 8

思路

因为 nn 的数据范围十分人性,所以可以使用 dfs 进行暴搜通过这道题目。

在函数中传入两个参数 xxss 分别表示现在正在选择的人与获得的价值。

x=2×n+1x=2\times n+1 时,说明前面的 2×n2\times n 个人已经全部访问完了,就应该储存答案接着返回了。

为了使选择的人不重复,应该使用 visvis 数组记录已经选择的人,避免重复选择。

要注意,在操作中 xx 这个人不光可以选择别人还可以被别人选择,所以应该有直接访问下一层的操作。

AC Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=100;
int n,a[N][N],ans;
bool vis[N];
void dfs(int x,int s){
	if(x==n+1){
		for(int i=1;i<=n;i++) if(!vis[i]) return ;
		ans=max(ans,s);
		return;
	}if(vis[x]){dfs(x+1,s);return;} //已经被前面的人选择过了
	vis[x]=1;
	for(int i=1;i<x;i++){
		if(!vis[i]){
			vis[i]=1;
			dfs(x+1,s^a[min(x,i)][max(x,i)]); //因为输入的时候 j 全部大于 i
			vis[i]=0;
		}
	}vis[x]=0,dfs(x+1,s); //给别人选择自己的机会
}
void solve(){
	cin>>n;
	n*=2;
	for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) cin>>a[i][j];
	dfs(1,0);
	cout<<ans<<endl;
}signed main(){
	int T=1;//cin>>T;
	while(T--) solve();
	return 0;
}