[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;
}
posted @ 2024-07-14 13:35  未抑郁的刘大狗  阅读(4)  评论(0编辑  收藏  举报