目录
一、问题简述
二、分析
三、代码展示
四、结果验证
一、问题简述
问题描述:羽毛球队有男女运动员各n人。给定2个n*n矩阵P和Q。P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞争优势;Q[i][j]是男运动员i和女运动员j配合的女运动员竞争优势。由于技术配合和心理状态等各种因素影响,P[i][j]不一定等于Q[i][j]。男运动员i和女运动员j配对组成的男女双方竞赛的优势为P[i][j]*Q[i][j]。设计一个算法,计算男女运动员最佳配对方法,使各组男女双方竞赛优势的总和达到最大。
算法设计:设计一个算法,对于给定的男女运动员竞赛优势,计算男女运动员最佳配对法,使各组男女运动员竞赛优势的总和达到最大化。
数据输入:由文件input.txt给出输入数据,第一行有1个正整数n(1<=n<=20)。接下来的第2n行,每行n个数。前n行是p,后n行是q。
结果输出:将计算的男女双方竞赛优势的总和最大值输出到文件output.txt中
输入文件实例input.txt 输出文件实例output.txt
3 52
10 2 3
2 3 4
3 4 5
2 2 2
3 5 3
4 5 1
二、分析
1、该问题要求的是男女运动员最佳配对的方法,使得各组男女双方竞争优势总和达到最大,那么我们需要把所有的搭配方法都求出来,完后通过比较,不断双更新maxValue的值
2、那么总的有几种搭配方案:男女人数都是相同的,而且都是一对一的搭配,我们把男生固定不变,通过变换女生顺序来进行搭配,那么女生的顺序有多少种,就会有多少种搭配方式。
3、女生有多少种搭配方式:全排列
backtrack(int t) //搜索树的第t层
若 t>n, 判断 记录 返回
对 i = t : n
| 交换 x[t] 和 x[i]
| 若 满足 Constraint(t) 且 Bound(t) //约束和限界条件
| 则 backtrack(t+1);
| 交换 x[t] 和 x[i]
执行backtrack(1)
初始x[i]=i
4、剪枝
(1)开辟一个新的数组,存储两个运动员搭配时的竞赛优势,并且以男运动员为固定,找出他的最佳搭配,并记录最大竞争优势。使用递归,如果剩下的最大竞争优势相加无法超过以得的最大值,那么就进行“剪枝”,结束递归
(2)对于数组,每一行的最大值就是这个男生i和这个所有女生搭配得到的最大竞争优势,这个女生就是j
(3)每一步进行计算,随时得到的结果进行比较。
三、代码展示
#include<stdio.h>
#include<stdlib.h>
#define N 21
int n; //存放男女运动员的个数
int P[N][N],Q[N][N]; //分别用于存放男、女运动员的竞赛优势
int x[N]; //x[N]用于存放男运动员N配对后的双方竞赛优势
int opt[N]; //记录每个男生匹配后可达到的最大双方竞赛优势
int tempValue=0,maxValue=0; //tempValue为竞争优势, maxValue为最大竞争优势
void compute() //计算竞争优势
{
tempValue = 0;
for(int i=1;i<=n;i++)
{
tempValue += P[i][x[i]]*Q[x[i]][i];
}
if(tempValue>maxValue)
{
maxValue = tempValue;
for(int i=1;i<=n;i++)
{
opt[i] = x[i];
}
}
}
void traceback(int t) //回溯法
{
int i,j,temp;
if(t>n)
{
compute();
}
for(i=t;i<=n;i++)
{
temp = x[i];
x[i] = x[t];
x[t] = temp;
traceback(t+1);
temp = x[i];
x[i] = x[t];
x[t] = temp;
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
x[i] = i;
}
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]);
}
}
traceback(1);
printf("%d\n",maxValue);
return 0;
}
四、结果验证
那让我们一起来检验一下他的正确性吧~
(1)在代码相同路径下建立两个题目要求所需要的文件output.txt和input.txt
(2)在input.txt文件中输入相关的数据
(3)运行一下代码吧
(4)运行成功后,打开output.txt文件夹看看结果
这样就验证结束啦~
大家还可以更具自己的想法对程序进行改进,得到性能更好,效果更棒的程序哦~