[ABC236D] Dance 题解
题目大意
有 \(2n\) 个人,每第 \(i\) 个人与第 \(j\) 个人一组会产生 \(a_{i,j}\) 的价值,求所有价值异或的最大值,其中 \(1\le n \le 8\)。
思路
因为 \(n\) 的数据范围十分人性,所以可以使用 dfs 进行包搜通过这道题目。
在函数中传入两个参数 \(x\) 与 \(s\) 分别表示现在正在选择的人与获得的价值。
当 \(x=2\times n+1\) 时,说明前面的 \(2\times n\) 个人已经全部访问完了,就应该储存答案接着返回了。
为了使选择的人不重复,应该使用 \(vis\) 数组记录已经选择的人,避免重复选择。
要注意,在操作中 \(x\) 这个人不光可以选择别人还可以被别人选择,所以应该有直接访问下一层的操作。
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;
}