题目 | Dance
AtCoder Beginner Contest 236
D - Dance
https://atcoder.jp/contests/abc236/tasks/abc236_d
Time Limit: 2 sec / Memory Limit: 1024 MB
Score :
Problem Statement
If Person
If the
Print the maximum possible total fun of the ball when the
Constraints
- All values in input are integers.
Input
Input is given from Standard Input in the following format:
Output
Print the maximum possible total fun of the ball.
Sample Input 1
2
4 0 1
5 3
2
Sample Output 1
6
Let
- Group into
. The total fun of the ball here is . - Group into
. The total fun of the ball here is . - Group into
. The total fun of the ball here is .
Therefore, the maximum possible total fun of the ball is
Sample Input 2
1
5
Sample Output 2
5
There will be just a pair of Person
Sample Input 3
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
1073289207
我的笔记
本题在做的时候,确实想到的是 DFS 遍历,但因为没有仔细思考时间复杂度到底是多少,导致选用了错误的方法最后TLE。
错误思路
题目给出了每两个人之间的喜好值,于是我就直来直去,想着直接用喜好值 DFS,选了
正确思路
首先考虑最大情况一共有 16 个人分 8 组,我们可以一个个遍历,第一组第一个有 16 种选法,第一组第二个有 15 种选法,第二组第一个有 14 种选法……时间复杂度为
但是这种选法有非常多重复的情况,例如:
为了规避这种重复,我们就要有序地进行选择,让每一组的第一个从小到大排列,例如
实现这种顺序的方法就是,每组第一个人选择最小的未选择的那个。这样时间复杂度为
还有一点是,通过一个 vector 存储选择的方式,在 DFS 完成时再进行异或运算得出结果,免去了每一步都进行异或操作,节省时间。
源码
#include <bits/stdc++.h>
using namespace std;
int N;
int A[20][20];
bool vis[20];
int ans = 0;
vector<pair<int, int>> v;
void dfs()
{
if (v.size() == N)
{
int ret = 0;
for (auto it = v.begin(); it != v.end(); ++it)
{
ret ^= A[it->first][it->second];
}
ans = max(ret, ans);
return;
}
int a;
for (int i = 1; i <= 2 * N; i++)
{
if (!vis[i])
{
a = i;
vis[a] = true;
break;
}
}
for (int i = 1; i <= 2 * N; i++)
{
if (!vis[i])
{
vis[i] = true;
v.push_back({a, i});
dfs();
vis[i] = false;
v.pop_back();
}
}
vis[a] = false;
}
int main(void)
{
ios::sync_with_stdio(false);
cin >> N;
for (int i = 1; i <= 2 * N - 1; i++)
{
for (int j = i + 1; j <= 2 * N; j++)
{
cin >> A[i][j];
}
}
dfs();
cout << ans << endl;
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi