题目:
羽毛球队有男女运动员各n人。给定2个n*n矩阵P和Q。P[i][j]是男运动员i和女运动员j,配对组成混合双打的男运动员竞赛优势,Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势。由于技术配合和心理状态等各种因素影响,P[i][j]不一定等于Q[j][i]。男运动员i和女运动员j配对组成混合双打的男女双方竞赛优势为P[i][j]*Q[j][i]。设计一个算法,计算男女运动员最佳配对方案,使各组男女双方竞赛优势的总和达到最大。
回溯法程序:
#include "stdafx.h"
#include<iostream>
using namespace std;
//回溯法
#define NUM 100
int best[NUM]; //最佳组合方式(女运动员的搭配顺序,男运动员按编号顺序站定)
int w[NUM]; //组合方式(中间过程,女运动员的搭配顺序,男运动员按编号顺序站定)
int p[NUM][NUM]; //男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势
int q[NUM][NUM]; //女运动员i和男运动员j配合的女运动员竞赛优势
int answer = -1;
//交换函数
void SwapInt(int *a,int *b)
{
int t = *a;
*a = *b;
*b = t;
}
//更新函数
void Update(int n)
{
int sum = 0;
//计算当前组合的优势和
for(int i=1;i<=n;i++)
sum += p[i][w[i]] * q[w[i]][i];
//如果比之前的组合的优势和大
if(sum>answer)
{
//更新优势和
answer = sum;
//更新组合方式
for(int i=1;i<=n;i++)
best[i] = w[i];
}
}
//求最佳组合函数
void Backtrack(int level,int n)
{
if(level>n)
Update(n);
else
{
for(int i=level;i<=n;i++)
{
//交换顺序
SwapInt(&w[level],&w[i]);
//求组合优势和
Backtrack(level+1,n);
//将次序交换回来,便于下次比较
SwapInt(&w[level],&w[i]);
}
}
}
int main()
{
int n,i,j;
cout << "enter the number of the player teams: ";
cin >> n;
//输入P,Q矩阵
cout << "input P[i][j]:" << endl;
for(i=1;i<=n;i++)
{
w[i] = i;
best[i] = w[i];
cout << "\t女" << i <<' ';
}
cout << endl;
for(i=1;i<=n;i++)
{
cout << "P[" << i << "][:]: ";
for(j=1;j<=n;j++)
cin >> p[i][j];
}
cout << "input Q[i][j]:" << endl;
for(i=1;i<=n;i++)
cout << "\t男" << i <<' ';
cout << endl;
for(i=1;i<=n;i++)
{
cout << "Q[" << i << "][:]: ";
for(j=1;j<=n;j++)
cin >> q[i][j];
}
//求最优解
Backtrack(1,n);
//输出最优解(女运动员的搭配顺序,男运动员按编号顺序站定)
cout << "男运动员按编号顺序站定,女运动员的搭配顺序为:" << endl;
for(i=1;i<=n;i++)
cout << best[i] << ' ';
system("pause");
return 0;
}
运行结果如下:
一般思路程序如下:
#include "stdafx.h"
#include<iostream>
using namespace std;
//交换函数
void Swap(int *a,int *b)
{
int t = *a;
*a = *b;
*b = t;
}
int main()
{
int n,i,j;
int sum;
int bestSum=0; //最大优势
cout << "enter the number of the player teams: ";
cin >> n;
//动态创建各数组
int *best = new int[n+1]; //最佳组合方式(女运动员的搭配顺序,男运动员按编号顺序站定)
int *w = new int[n+1]; //组合方式(中间过程,女运动员的搭配顺序,男运动员按编号顺序站定)
int **p = new int*[n+1]; //男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势
for(i=0;i<=n;i++)
p[i] = new int[n+1];
int **q = new int*[n+1]; //女运动员i和男运动员j配合的女运动员竞赛优势
for(i=0;i<=n;i++)
q[i] = new int[n+1];
//输入P,Q矩阵
cout << "input P[i][j]:" << endl;
for(i=1;i<=n;i++)
{
w[i] = i;
best[i] = w[i];
cout << "\t女" << i <<' ';
}
cout << endl;
for(i=1;i<=n;i++)
{
cout << "P[" << i << "][:]: ";
for(j=0;j<n;j++)
cin >> p[i][j];
}
cout << "input Q[i][j]:" << endl;
for(i=1;i<=n;i++)
cout << "\t男" << i <<' ';
cout << endl;
for(i=1;i<=n;i++)
{
cout << "Q[" << i << "][:]: ";
for(j=1;j<=n;j++)
cin >> q[i][j];
}
//求最佳组合
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
int k=0;
sum = 0;
//求当前组合的优势和
for(k=1;k<=n;k++)
sum = sum + p[i][w[i]]*q[w[i]][i];
//如果当前组合的优势和大于之前组合的优势和
if(sum > bestSum)
{
//更新优势和
bestSum = sum;
//更新组合方式
for(k=1;k<=n;k++)
best[k] = w[k];
}
//交换组合方式
Swap(&w[i],&w[j]);
}
//输出最优解(女运动员的搭配顺序,男运动员按编号顺序站定)
cout << "男运动员按编号顺序站定,女运动员的搭配顺序为:" << endl;
for(i=1;i<=n;i++)
cout << best[i] << ' ';
//释放空间(动态分配的数组空间)
delete [n+1]best;
delete [n+1]w;
for(i=0;i<=n;i++)
{
delete p[i];
p[i] = NULL;
}
delete [n+1]p;
p = NULL;
for(i=0;i<=n;i++)
{
delete q[i];
q[i] = NULL;
}
delete [n+1]q;
q = NULL;
system("pause");
return 0;
}
运行结果如下: