#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
//最佳运动员配对问题
/*
剪枝:
1.由男性运动员选择女性运动员进行配对。根据输入,每个男性都有最佳的女运动员与之配对。
若[当前还未配对的男性运动员均选择最佳配对(不考虑女运动员是否已配对)时的配对值之和]
与[当前已完成配对的男运动员的配对值之和]相加仍未能优于当前最优解,则该子树上不会存在
最优解,剪枝。
2.每名女性运动员只能和一名男性运动员配对
*/
const int N = 10;
int P[N][N];
int Q[N][N];
int n;
int Max[N];//贪心最大配对记录(提前设置完毕)
//
int pq[N];//女远动员的排列(第i位男士配第pq[i]位女性)
int endsum[N];//结果配对记录
int Maxsum;//当前配对和
int Maxcount;//(最终)最大配对和
//
void getMaxsum(int x)//x排列树层数
{
if(x>n){
if(Maxsum>Maxcount){
Maxcount=Maxsum;
for(int i=1;i<=n;i++){
endsum[i]=pq[i];//最优解替换
}
}
return;
}
int cnt=0;//求出剩余最大贪心配对和
for(int i=x+1;i<=n;i++){
cnt=cnt+Max[i];
}
for(int j=x;j<=n;j++){
swap(pq[j],pq[x]);
Maxsum+=P[x][pq[x]]*Q[pq[x]][x];
if((cnt+Maxsum)>Maxcount)//剪枝
{
getMaxsum(x+1);
}
Maxsum-=P[x][pq[x]]*Q[pq[x]][x];
swap(pq[x],pq[j]);
}
}
int main()
{
cout<<"please enter the number of the athletes"<<endl;
cin>>n;
//cout<<"please enter the P matrix"<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>P[i][j];
}
}
//cout<<"please enter the Q matrix"<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>Q[i][j];
}
}
for(int i=1;i<=n;i++){
pq[i]=i;
}
//设置Max数组
for(int i=1;i<=n;i++){
int temp=0;
for(int j=1;j<=n;j++){
if(P[i][j]*Q[j][i]>temp)temp=P[i][j]*Q[j][i];
}
Max[i]=temp;
}
getMaxsum(1);
//结果输出
cout<<Maxcount<<endl;
for(int i=0;i<n;i++){
cout<<endsum[i+1]<<" ";
}cout<<endl;
system("pause");
return 0;
}
/*
3
10 2 3
2 3 4
3 4 5
2 2 2
3 5 3
4 5 1
*/
最佳运动员配对问题:回溯法
最新推荐文章于 2024-06-12 18:28:23 发布