运动员最佳配对问题

一个羽毛球队有男女运动员各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] + " ");
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值