程序基本算法习题解析 设计一个算法,计算男女运动员最佳配对方案,使各组男女双方竞赛优势的总和达到最大。

题目:

羽毛球队有男女运动员各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;
}

运行结果如下:

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值