排列数
排列数:举个例子,1, 2, 3的排列数就是:
3 1 2
3 2 1
1 3 2
1 2 3
2 1 3
2 3 1
那么如何得到这个排列数呢?看这个回溯法搜索排列数框架:
void Backtrack(int t) {
if (t > n) {
output();
}
else {
for (int i = t; i <= n; i++) {
Swap(x[t], x[i]);
if (Constraint(t) && Bound(t)) {
Backtrack(t + 1);
}
Swap(x[t], x[i]);
}
}
}
用C++写出来就是:
#include <iostream>
using namespace std;
int a[10];
void Backtrack(int t) {
if (t > 3) {
for (int i = 0; i < 3; i++) {
cout << a[i] << " ";
}
cout << endl;
return ;
}
else {
for (int i = t; i <= 3; i++) {
int temp = a[i - 1];
a[i - 1] = a[t - 1];
a[t - 1] = temp;
Backtrack(t + 1);
temp = a[i - 1];
a[i - 1] = a[t - 1];
a[t - 1] = temp;
}
}
}
int main() {
for (int i = 0; i < 3; i++) {
cin >> a[i];
}
Backtrack(1);
}
运行例子:
1 2 3
3 1 2
3 2 1
1 3 2
1 2 3
2 1 3
2 3 1
排列数的应用
8604 运动员最佳配对问题
羽毛球队有男女运动员各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]。
设计一个算法,计算男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大。
编程任务:设计一个算法,对于给定的男女运动员竞赛优势,计算男女运动员最佳配对法,使各组男
女双方竞赛优势的总和达到最大。
如下面sample的数据:
P=
10 2 3
2 3 4
3 4 5
Q=
2 2 2
3 5 3
4 5 1
最大的男女双方竞赛优势总和为:102 + 45 + 4*3 = 52
最佳搭配为:(女1,男1)(女2,男3)(女3,男2)
解析
对于这个问题,我们可以对男生进行全排列,然后与女生相乘。
源代码
#include <iostream>
using namespace std;
// 这个表示个数、m表示男生,w表示女生
int n, m[20][20], w[20][20];
// 表示总分数
int sum = 0, a[20];
void Backtrack(int t) {
if (t > n) {
int temp = 0;
for (int i = 0; i < n; i++) {
temp += m[a[i]][i] * w[i][a[i]];
}
if (temp > sum) {
sum = temp;
}
}
else {
for (int i = t; i <= n; i++) {
int temp = a[i - 1];
a[i - 1] = a[t - 1];
a[t - 1] = temp;
Backtrack(t + 1);
temp = a[i - 1];
a[i - 1] = a[t - 1];
a[t - 1] = temp;
}
}
}
int main(){
cin >> n;
for (int i = 0; i < n; i++) {
a[i] = i;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> m[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> w[i][j];
}
}
Backtrack(1);
cout << sum;
return 0;
}