一个羽毛球队有男女运动员各n人,给定2个n*n矩阵P和Q。P[i][j]是男运动员i和女运动员j配对组成混合双打是的竞赛优势;Q[i][j]则是女运动员i和男运动员j配合是的竞赛优势。显然,由于技术的配合和心理状态等各种因素的影响,P[i][j]不一定等于Q[j][i]。设计一个算法,计算出男女运动员的最佳配对法,使各组男女双方竞赛优势乘积的总和达到最大。
package Test.qddx;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class Sports {
public static int[] best = new int[100];// 定义最佳的选择
public static int[] w = new int[100];
public static int[][] p = new int[100][100];// 定义数组大小
public static int[][] q = new int[100][100];
public static int answer = -1;// 定义初始值
public static void swap(int[] w, int a, int b) {
int temp = 0;
temp = w[a];
w[a] = w[b];
w[b] = temp;
}
public static void update(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += p[i][w[i]] * q[w[i]][i];
// 打印出每一步的过程
// System.out.println("p[" + i + "][" + w[i] + "] * q[" + w[i] +
// "]["
// + i + "]" + "=" + p[i][w[i]] * q[w[i]][i]);
// System.out.println(p[i][w[i]] * q[w[i]][i]);
}
// System.out.println("sum=" + sum);
if (sum > answer) {
answer = sum;
for (int i = 1; i <= n; i++)
best[i] = w[i];// 将最佳的路径存入数组
}
}
public static void backtrack(int level, int n) {
if (level > n)
update(n);
else
for (int i = level; i <= n; i++) {
// swap(w, w[level], w[i]);
swap(w, level, i);// 交换路径
backtrack(level + 1, n); // 深度优先遍历 ,递归处理右子树
swap(w, level, i);// 将路径重置
// swap(w, w[level], w[i]);
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new FileReader("E:/input.txt"));// 读取文件
BufferedWriter bw = new BufferedWriter(new FileWriter("E:/output.txt"));// 写入文件
int count = -1;// 用来计数
String s = null;
String[] str = null;
int n = 0;// 男女运动员配对的数量
while ((s = br.readLine()) != null) {// 将从input.txt读取数字 写入数组
count++;
// System.out.println(count);// 打印出计数的值
str = s.split(" ");
if (str.length == 1) {
n = Integer.parseInt(str[0]);
System.out.println("男女运动员的各自数量:" + n);
} else if (count <= n) {// 给男运动员赋值
for (int i = 1; i <= n; i++) {
p[count][i] = Integer.parseInt(str[i - 1]);
// System.out.print(p[count][i] + " ");
}
// System.out.println();
} else {// 给女运动员赋值
for (int i = 1; i <= n; i++) {
q[count - n][i] = Integer.parseInt(str[i - 1]);
// System.out.print(q[count - n][i] + " ");
}
// System.out.println();
}
}
for (int i = 1; i <= n; i++) {// 递归退层时 将该段加入剩余路径当中
w[i] = i;
}
backtrack(1, n);
// update(n);
System.out.println("最优解为:" + answer);
bw.write(String.valueOf(answer));// 向文件中写入
bw.flush();
bw.close();
br.close();
// 打印出最优解
System.out.print("最优选择为:");
for (int i = 1; i <= n; i++) {
System.out.print(best[i] + " ");
}
}
}