运动员最佳配对问题
来源:互联网 发布:淘宝卖家群 编辑:程序博客网 时间:2024/05/17 02:02
西安交大 软件53 蔡少斐
题号:6_5
题目叙述:
羽毛球队有男女运动员各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]。
设计一个算法,计算男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大。
编程任务:设计一个算法,对于给定的男女运动员竞赛优势,计算男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大。
输入格式
输入数据第一行有1 个正整数n (1≤n≤10)。接下来的2n行,每行n个数。前n行是P,后n行是Q。
输出格式
将计算出的男女双方竞赛优势的总和的最大值输出。
输入样例
3
10 2 3
2 3 4
3 4 5
2 2 2
3 5 3
4 5 1
输出样例
52
题目解答:
这道题目共有n!种配对情况,也就是相当于固定男运动员,然后对女运动员进行一次全排列,并求出对应的优势之和的最大值,本题可以用回溯法,也可以用分支限界法,在使用分支限界法的时候,关键是在于设计上界函数。
在这里,我们把上界函数定义为:剩下的未配对的女运动员(不考虑男运动员配对情况下)所能达到的优势最大值之和(记为r)与当前配对已达到的优势(记为sum)之和。在程序里体现如下:
在一开始时候,r被初始化为:
其中maxout的定义为:
在使用分支限界法的时候,一旦有一个叶节点出来,那么就立即结束算法,因为最先出来的叶节点必定是最优解。
代码实现:
#include<algorithm>#include<iostream>#include<queue>#include<vector>#include <cstdio>usingnamespace std;const int MAX = 20;int P[MAX][MAX];int Q[MAX][MAX];int maxout[MAX];int n;structnode { int id; int sum; int r; int up; int *x;};structcmp { bool operator()( node* a, node* b ) { return(a->up < b->up); }};voidsolve(){ int ans= 0; priority_queue<node*,vector<node*>, cmp> que; node *E = new node(); E->id =1; E->sum =0; E->r =0; E->up =0; for ( int i = 1; i <= n; i++ ) { E->r += maxout[i]; } E->up =E->r; E->x =new int[n + 1]; for ( int i = 1; i <= n; i++ ) { E->x[i] = i; } while ( E->id != n + 1 ) { for ( int i = E->id; i <= n;i++ ) { node* nE = new node(); nE->id = E->id + 1; nE->x = new int[n + 1]; for ( int t = 1; t <= n;t++ ) { nE->x[t] =E->x[t]; } nE->x[E->id] = E->x[i]; nE->x[i] = E->x[E->id]; nE->sum = E->sum +P[E->id][nE->x[E->id]] * Q[nE->x[E->id]][E->id]; nE->r = E->r - maxout[E->id]; nE->up = nE->sum + nE->r; que.push( nE ); } if ( !que.empty() ) { E= que.top(); que.pop(); }else { ans = 0; break; } } ans = E->sum; cout << ans << endl;} intmain(){ cin >> n; for ( int i = 1; i <= n; i++ ) { for ( int j = 1; j <= n; j++ ) { cin >> P[i][j]; } } 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++ ) { int ma = 0; for ( int j = 1; j <= n; j++ ) { ma = max( ma, Q[i][j] *P[j][i] ); } maxout[i] = ma; } solve(); return(0);} /* * 3 * 10 2 3 * 2 3 4 * 3 4 5 * 2 2 2 * 3 5 3 * 4 5 1 */
运行结果:
- 运动员最佳配对问题
- 运动员最佳配对问题
- 运动员最佳配对问题
- 8604 运动员最佳配对问题
- 运动员最佳配对问题实验报告
- 运动员最佳配对问题(回溯)
- 运动员最佳配对问题5_4 6_5
- 运动员最佳匹配问题
- 运动员最佳匹配问题
- 最佳运动员搭配问题
- 最佳运动员配对问题-婚姻搭配-最小重量机器设计问题-回溯法
- 洛谷P1559 运动员最佳匹配问题
- Luogu 1559 运动员最佳匹配问题
- 洛谷P1559 运动员最佳匹配问题
- 运动员打靶问题
- 运动员分组问题
- 运动员指派问题
- 运动员打靶问题
- 字符串处理
- 基于JavaMail的Java邮件发送:复杂邮件发送
- Python日志输出——logging模块
- js获取日期的代码
- 两个字符串是变位词
- 运动员最佳配对问题
- Oracle将与Kubernetes合作推出DevOps解决方案!
- 二进制中1的个数(java版)
- 英文单词
- 机器学习、深度学习过程中用到的工具。
- Oracle数据库常用命令
- python ethereum 代码分析
- @Autowired注入dao时失败
- 逻辑门