D - Dance /
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 400 points
Problem Statement
2N people numbered 1,2,…,2N attend a ball. They will group into N pairs and have a dance.
If Person i and Person j pair up, where i is smaller than j, the affinity of that pair is A
i,j
.
If the N pairs have the affinity of B
1
,B
2
,…,B
N
, the total fun of the ball is the bitwise XOR of them: B
1
⊕B
2
⊕⋯⊕B
N
.
Print the maximum possible total fun of the ball when the 2N people can freely group into N pairs.
Constraints
1≤N≤8
0≤A
i,j
<2
30
All values in input are integers.
Input
Input is given from Standard Input in the following format:
N
A
1,2
A
1,3
A
1,4
⋯ A
1,2N
A
2,3
A
2,4
⋯ A
2,2N
A
3,4
⋯ A
3,2N
⋮
A
2N−1,2N
Output
Print the maximum possible total fun of the ball.
Sample Input 1
Copy
2
4 0 1
5 3
2
Sample Output 1
Copy
6
Let {i,j} denote a pair of Person i and Person j. There are three ways for the four people to group into two pairs, as follows.
Group into {1,2},{3,4}. The total fun of the ball here is A
1,2
⊕A
3,4
=4⊕2=6.
Group into {1,3},{2,4}. The total fun of the ball here is A
1,3
⊕A
2,4
=0⊕3=3.
Group into {1,4},{2,3}. The total fun of the ball here is A
1,4
⊕A
2,3
=1⊕5=4.
Therefore, the maximum possible total fun of the ball is 6.
Sample Input 2
Copy
1
5
Sample Output 2
Copy
5
There will be just a pair of Person 1 and Person 2, where the total fun of the ball is 5.
Sample Input 3
Copy
5
900606388 317329110 665451442 1045743214 260775845 726039763 57365372 741277060 944347467
369646735 642395945 599952146 86221147 523579390 591944369 911198494 695097136
138172503 571268336 111747377 595746631 934427285 840101927 757856472
655483844 580613112 445614713 607825444 252585196 725229185
827291247 105489451 58628521 1032791417 152042357
919691140 703307785 100772330 370415195
666350287 691977663 987658020
1039679956 218233643
70938785
Sample Output 3
Copy
1073289207
题意 :
- 有2n个人,要分成n对,已知任意两人之间的好感值,求如何分配使得好感值异或和最大
思路 :
- 发现数据范围很小,足够列举所有将2n个人分成n对的情况,然后输出其中最大的结果
- 但如果分别考虑这2n个位置,时间复杂度有 16 ∗ 15 ∗ 14 ∗ . . ∗ 1 > 2 ∗ 1 0 13 16 * 15 * 14 * .. * 1 > 2*10^{13} 16∗15∗14∗..∗1>2∗1013,会超时
- 我们发现,考虑当前一对时,我们只要都让这对中第一个位置是当前可以使用的人中最小的编号,然后枚举第二个位置求最大值,这样也可以遍历出所有的情况(因为我们只求最大值,不是求具体方案),这样,时间复杂度就优化成 15 ∗ 13 ∗ 11 ∗ . . . ∗ 1 = 2027025 15 * 13 * 11 * ... * 1 = 2027025 15∗13∗11∗...∗1=2027025
- 更妙的是,发现题目给我们的数据也是 小的编号-大的编号,这样我们枚举之后要计算当前结果只要直接用这个数组就可以了,不需要再复制一份数组
语法 :
- 因为vec内容存的是pair,因此当其中有n对时,就是
vec.size() == n
,也就是说,判断vector容器的size,要根据它存的内容的类型,以一个内容物为一个单位
#include <iostream>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
const int N = 20;
int n;
int a[N][N];
bool st[N];
vector<PII> vec;
int calc()
{
if (vec.size() == n)
{
int ret = 0;
for (auto p : vec) ret ^= (a[p.first][p.second]);
return ret;
}
int l;
for (int i = 1; i <= 2 * n; i ++ )
if (!st[i])
{
l = i; break;
}
st[l] = true;
int ret = 0;
for (int i = 1; i <= 2 * n; i ++ )
if (!st[i])
{
vec.push_back({l, i});
st[i] = true;
ret = max(ret, calc());
st[i] = false;
vec.pop_back();
}
st[l] = false;
return ret;
}
int main()
{
cin >> n;
for (int i = 1; i <= 2 * n - 1; i ++ )
for (int j = i + 1; j <= 2 * n; j ++ )
cin >> a[i][j];
cout << calc();
}