1559 运动员最佳匹配问题
看到题面这么短,我好开心啊
给定两个数组,p[i][j]是男女双打,男优势;Q[i][j]是男女双打,女优势;两个人的优势便是p[i][j]*Q[i][j],设计一个算法,使得两个优势总和最大
很明显是一个二分图算法,搜索的原因便是搜索二分图
当然这个题乱七八糟的做法什么都有KM算法,最大流,不过我还是用搜索加剪枝吧
搜索每一个男运动员,为他去搜索匹配每一个没有用过的女运动员,最后算出每种匹配的竞赛优势
最后在所有方案中选最大的
不过,这种做法会超时,TLE两个点
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,p[25][25],q[25][25],s,ans;
bool v[25]; //需要确定每个女运动员是否已匹配。
void dfs(int x)
{
if(x>n)//搜索结束,记录答案
{
ans=max(s,ans);
return;
}
for(int i=1;i<=n;i++)//接着搜
{
if(!v[i])//未访问
{
v[i]=1;
s += p[x][i]*q[i][x];//计算方案
dfs(x + 1);//接着往下搜索
s-=p[x][i]*q[i][x];//回溯
v[i]=0;
}
}
}
int main()
{
cin >> n;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= n;j++)
scanf("%d",&p[i][j]);//输入p数组
for (int i = 1;i <= n;i++)
for (int j = 1;j <= n;j++)
scanf("%d",&q[i][j]);//输入q数组
dfs(1);//从第一个开始搜索
cout<<ans;
return 0;
}
众所周知,80分
我们也可以用剪枝来解决这个问题,看可以剪掉已经不可能的情况,在任何一种搜索的情况的竞赛优势理论+原来已搜索部分仍然没有之前搜的答案大,说明这条路不可能搜了,直接结束
不一定可以配出此情况,但是理论最大值肯定比实际最大值要大,所以如果理论最大值都没有已搜过的完整路的答案大,实际上按这条路搜下去必定无法更新答案
所以,就没必要浪费时间
这个算法好像是A*搜索当中的思想
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,p[25][25],q[25][25],maxx[25],s,ans;
bool v[25];
void dfs(int x)//搜索层数
{
int sum = s;
for(int i = x;i <= n;i++)//从当前层数往后搜索
{
int maxx = 0;//理论最大值
for(int j=1;j<=n;j++)
maxx=max(maxx,p[i][j]*q[j][i]);//比较最大的匹配优势
sum += maxx;//然后计算理论最大值
}
if(sum<=ans) return;//如果当前的理论比不上答案,剪枝
if(x>n)//达到层数
{
ans=max(s,ans);//记录答案
return;
}
for(int i=1;i<=n;i++)
if (!v[i])//未被访问的点
{
v[i]=1;
s+=p[x][i]*q[i][x];//计算答案
dfs(x+1);//下一层
s-=p[x][i]*q[i][x];//回溯
v[i]=0;
}
}
int main()
{
cin >> n;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= n;j++)
scanf("%d",&p[i][j]);
for (int i = 1;i <= n;i++)
for (int j = 1;j <= n;j++)
scanf("%d",&q[i][j]);
dfs(1);
cout<<ans<<endl;
return 0;
}
本文介绍了一道算法题目——1559 运动员最佳匹配问题,涉及男女双打比赛,目标是最大化双方优势总和。通过二分图算法,结合搜索与剪枝策略来优化解决方案,以避免超时错误。文章讨论了如何利用搜索加剪枝的方法,以及剪枝在搜索过程中的应用,以提高算法效率。
2303

被折叠的 条评论
为什么被折叠?



