代码源:809、最后的舞会

375 阅读1分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路 logo.png

题目描述

这是4月24日代码源div2的每日一题。

最后的舞会 - 题目 - Daimayuan Online Judge

老师为即将毕业的同学们准备了一场舞会,有2N个同学会参加这场舞会,他们会被分成N对跳舞,每个人有一个编号,如果编号为i的同学和编号为j的同学配对,那么这一对的满意度是Ai,j(i<j),我们规定这个舞会的满意度为每一队的满意度的异或和,也就是说,当同学们分成N组后,第i对同学的满意度为Ai,那么舞会的满意度为A1⊕A2⊕...AN 请你求出本场舞会满意度的最大值

输入描述

第一行给出一个数N,有2N个人参加舞会

接下来给出一个矩阵表示i和j配对时的满意度

A1,2,A1,3,...A1,2N A2,3,...A2,2N . . . A2N−1,2N 其中1≤N≤8,0≤Ai,j≤2^30

输出描述

输出本场舞会满意度的最大值

样例输入

2
4 0 1
5 3
2

样例输出

6

样例解释

如果{1,2},{3,4},ans=A1,2⊕A3,4=4⊕2=6

如果{1,3},{2,4},ans=A1,3⊕A2,4=0⊕3=3

如果{1,4},{2,3},ans=A1,4⊕A2,3=1⊕5=4

最后答案为max(6,3,4)=6

问题解析

这题可以直接暴力写。

枚举所有的组合,算每次组合的满意度,并在过程中维护最大值。比如你从1开始,选一个和1搭配的,然后再从剩下的人里选一个去做下一队的配对。这里n最多是8,2* n人就是16,此过程每次取一对人出来,那么可能的组合数就是 15 * 13 * 11 * 9…… * 1,并不会超时。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e6 + 50, MOD = 100003;
ll n, ans = 0, mx = 0;
vector<vector<ll>>v;
int mymap[20];

inline int read() {
	long long x = 0; char ch = getchar();
	while (ch < '0' || ch > '9') ch = getchar();
	while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
	return x;
}

inline void write(int x) {
	if (x > 9) write(x / 10);
	putchar(x % 10 | '0');
}

void dfs(int u, ll res, int x)
{
	mymap[u] = 1;
	for (int i = u + 1; i <= 2 * n; i++)
	{
		if (mymap[i] == 0)
		{
			ll ans = res ^ v[u][i];
			mymap[i] = 1;
			bool flag = true;
			int j = 1;
			for (; j < 2 * n; j++)
				if (mymap[j] == 0)
					break;
			if (j < 2 * n)
			{
				mymap[j] = 1;
				flag = false;
				dfs(j, ans, x + 1);
				mymap[j] = 0;
			}
			if (flag)
			{
				mx = max(mx, ans);
			}
			mymap[i] = 0;
		}
	}
	mymap[u] = 0;
}

int main()
{
	n = read();
	int  x;
	int m = 2 * n;
	v.push_back({ 0 });
	for (int i = 1; i < m; i++)
	{
		vector<ll>v0(2 * n + 1);
		for (int j = i + 1; j <= m; j++)
		{
			v0[j] = read();
		}
		v.push_back(v0);
	}
	dfs(1, 0, 0);
	write(mx);
	return 0;
}