此题是真的离谱,周赛第三题放个暴力,还把我难倒了是最气的。
此题是一个两两匹配的问题
思路1:排序
看到这个有点像区间问题,就想能不能排序后做,其实完全不行。
思路2:优先队列
两两运算结果排序,运算结果从大到小统计。
这种贪心的做法不对
思路3:暴力
平常就是暴力太少了,以至于到了该暴力的时候不会暴力。一开始的思路是求全排列,得到所有可能性,然后
(
m
!
)
2
(m!)^2
(m!)2做,但是超时。
之后才想到,根本不用,只要求出一个全排列就可以了,剩下的那个不动就行,这就是所有可能性。
class Solution {
typedef tuple<int, int, int> T;
public:
void dfs(vector<vector<int>> &ans, vector<int> &tmp, vector<int> &F, int ct, int m)
{
if(ct == m)
{
ans.push_back(tmp);
return;
}
for(int i=0;i<m;i++)
{
if(F[i])continue;
F[i] = 1;
tmp.push_back(i);
dfs(ans, tmp, F, ct+1, m);
tmp.pop_back();
F[i] = 0;
}
}
vector<vector<int>> getall(int m)
{
vector<vector<int>> ans;
vector<int> F(m);
vector<int> tmp;
for(int i=0;i<m;i++)
{
tmp.push_back(i);
F[i] = 1;
dfs(ans, tmp, F, 1, m);
tmp.pop_back();
F[i] = 0;
}
return ans;
}
int maxCompatibilitySum(vector<vector<int>>& students, vector<vector<int>>& mentors) {
int m = students.size(), n = students[0].size();
vector<vector<int>> v = getall(m);
int ans = 0, size = v.size();
for(int i=0;i<size;i++)
{
int tmp = 0;
auto p1 = v[i];
for(int k=0;k<m;k++)
{
auto mi = students[p1[k]];
for(int t=0;t<n;t++)
{
if(mi[t] == mentors[k][t])tmp++;
}
}
if(tmp > ans)ans = tmp;
}
return ans;
}
};