运动员最佳匹配问题(详解)

news2025/3/1 8:52:12

一、问题描述

羽毛球队有男女运动员各n人。给定2个n×n矩阵P和Q。
P[i][j]是男运动员i的女运动员j配对组成混合双打的男运动员竞赛优势;Q[i][j]是女运动员i和男运动员j配对的女运动员竞赛优势。由于技术配合和心理状态等各种因素影响,P[i][j]不一定等于Q[i][j]。男运动员i和女运动员j配对组成混合双打的男女双方竞赛优势为P[i][j]×Q[i][j]。
设计一个算法,计算男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大。
输入样例:(第一行是男队员(或女队员)的个数,第二、三、四行是男运动员i 和女运动员j配对组成混合双打的男运动员竞赛优势,第五、六、七行是女运动员i和男运动员j配合的女运动员竞赛优势)
3
10 2 3
2 3 4
3 4 5
2 2 2
3 5 3
4 5 1
输出样例:(第一行是竞赛优势的最大和)
52

二、算法思路

固定男运动员,对女运动员进行一次全排列,并求出每位男运动员能匹配到的最大优势值。本题共有n!种配对情况。

固定1号男运动员,让所有的n个女运动员与其匹配,经过n次匹配,分别保存每组男女运动员的匹配优势到res数组和最优的男女运动员优势到MaxSum数组。
其中,res数组是N×N的二维数组,用于保存每个男运动员匹配过的女运动员的优势;MaxSum是一个1×N的一维数组,用于保存每个男运动员的匹配的最佳女运动员的优势。

根据题目的输入样例可以得到以下的排列树:
在这里插入图片描述
固定男运动员选女运动员,构成一颗排列数。树的第i行表示第i个男运动员,树结点序号表示与当前行男运动员匹配的女运动员序号。如:第一行的1表示,第一个男运动员与第一个女运动员匹配的竞争优势是20。

剪枝策略

如下是第一步计算得到的MaxSum和res数组:
在这里插入图片描述
如下是第一个分支进行搜索的过程:
在这里插入图片描述

当搜索该子树时,Max=40,表示已经探索过的路线中得到的最优解是40。

此时,在该层进行剪枝的判断:
已经固定的运动员优势和为20+20=40,假设再贪心的加上剩下的运动员匹配优势的最大值为40+MaxSum[2]=40+12=52, 52>40,则还有可能得到更大的优势解,继续向下搜索。

若贪心的加上其余运动员匹配最大优势后,仍不能超过已经搜索出的最优解,那么向下搜完整颗子树也不会得到最优解,则要进行剪枝操作。因为再向下搜索的结果只可能是小于等于最大优势的。
这就是【剪枝操作】的核心思想!
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;

int n;
int boy[21][21], girl[21][21];
int Max = INT_MIN; //MAX代表男女双方竞赛优势的总和的最大值 用来返回指定整数类型所能表示的最小值。
int sum = 0;
int res[21][21]; //data[i][j]用于存放男运动员i配对后的双方竞赛优势
int maxSum[21];   //保存每个男生匹配后可达到的最大双方竞赛优势
int book[21];    //标记女运动员是否已经匹配 0未匹配 1已匹配

//Max:40 -> 52
void dfs(int t){
    if(t>=n)  //t到达n后,代表全部标记访问了,得到了最大值
    {
        Max = max(Max, sum);
        return;
    }
    int cnt = 0;
    //求t及t之后男生匹配女生的最大值的和
    for (int i = t; i < n;i++){
        cnt += maxSum[i];
        //假设的贪心的让每个男运动员匹配最优的女运动员
    }

    //剪枝函数:之前t个已经匹配好的男女运动员的sum与
    //之后的t->n-1个男女匹配的最大值加起来得到的Max比较
    //若前者<=Max,剪枝
    if(sum+cnt<Max)
        return;
        //若cnt>=Max,要继续向下搜索
        //从第t个男生开始匹配,找未匹配的女生
    for (int i = 0; i < n;i++){
        if(!book[i]){//若第i个女生未匹配
            book[i] = 1;
            sum += res[t][i];
            dfs(t + 1);
            book[i] = 0; //若第t个男生匹配女生i得到的sum不大于Max,则回溯
            sum -= res[t][i];
        }
    }
}

int main(){
    cin >> n;
    for (int i = 0; i < n;i++){
        for (int j = 0; j < n;j++){
            cin >> boy[i][j];
        }
    }
    for (int i = 0; i < n;i++){
        for (int j = 0; j < n;j++){
            cin >> girl[i][j];
        }
    }
    for (int i = 0; i < n;i++){
        for (int j = 0; j < n;j++){
            //对每个男生都求男女双方竞赛优势,能得到i*j种结果
            res[i][j] = boy[i][j] * girl[j][i];
            //记录每个男生匹配后可达到的最大双方竞赛优势,用于后面的剪枝
            maxSum[i] = max(maxSum[i], res[i][j]);
        }
    }
    dfs(0);
    cout << Max << endl;
    return 0;
}

参考博客:运动员最佳匹配问题【回溯算法】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/404897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LearnOpenGL-光照-6.多光源

本人刚学OpenGL不久且自学&#xff0c;文中定有代码、术语等错误&#xff0c;欢迎指正 我写的项目地址&#xff1a;https://github.com/liujianjie/LearnOpenGLProject 文章目录前言例子代码没有聚光灯效果有聚光灯效果前言 此节目的 综合2.5投光物&#xff0c;在此节实现一个场…

超越语言界限,ChatGPT进化之路——Visual ChatGPT

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️&#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

操作系统复习

熟练掌握操作系统的定义&#xff0c;操作系统的特征&#xff0c;操作系统的功能熟练掌握多道程序设计的概念&#xff0c;单道程序设计和多道程序设计的区别&#xff0c;多道程序设计的优点熟悉操作系统接口的主要功能&#xff0c;系统调用的基本概念、类型、实现。操作系统接口…

【Mysql】库的操作

一、sql分类 1.DDL&#xff08;Data Defination Language&#xff09;数据定义语言 定义数据时候使用的sql语言 creat:建表、drop:删表、alter:改变 2.DML&#xff08;Data Manipulation Language&#xff09;数据操纵语言 对数据进行操作的sql语言 insert:插入、delet…

【打造家庭服务器系列03】Frp 实现内网穿透

一、概述 为什么要搞frp&#xff0c;因为我们的服务器处于家里面的网络&#xff0c;是没有公网IP的&#xff0c;所以直接通过ssh连接服务器&#xff0c;此时就需要一个中转来实现转发。 二、服务端配置 - Frp Server 以腾讯云为例&#xff0c;阿里云也一样。Frp 官方文档 -…

chatPDF | 别再自己读文献了!让chatGPT来帮你读吧!~

1写在前面 自从chatGPT开放API以后&#xff0c;相关基于此的app也是层出不穷。&#x1f92a; ChatGPT API是基于OpenAI的自然语言处理模型的API。&#x1f9d0; 基于这个API&#xff0c;开发人员可以通过程序调用和使用ChatGPT模型来解决各种文本相关的任务。&#x1f609; 其实…

Ubuntu软件包管理之apt与apt-get的区别

目录apt和apt-get发展史apt和apt-get命令对比常用命令举例更新存储库索引升级已安装的包列出所有可用安装包关键字搜索安装包安装软件卸载软件查看安装包信息清理没用的依赖包清理下载的缓存包清理残余的配置文件查看安装包的依赖参考apt和apt-get发展史 Debian 使用一套名为 …

STM32—LCD1602

LCD1602&#xff08;Liquid Crystal Display&#xff09;是一种工业字符型液晶&#xff0c;能够同时显示 1602 即 32 字符(16列两行) 第 1 脚: VSS 为电源地 第 2 脚: VDD 接 5V 正电源 第 3 脚: VL 为液晶显示器对比度调整端,接正电源时对比度最弱&#xff0c;接地时对比度最…

C语言实现快速排序(hoare法、挖坑法、前后指针法与非递归实现)——不看后悔系列

目录 1. hoare法 方法与步骤 代码实现 2. 挖坑法 方法与步骤 代码实现 3. 前后指针法 方法与步骤 代码实现 4. 快速排序的缺点与优化 1.快速排序的缺点 2.快速排序的优化 ① 三数取中法选 key 代码实现 ② 小区间优化 代码实现 5. 快速排序的非递归实现 附录…

数据结构与算法基础(王卓)(16):KMP算法详解(代码实现)

实现代码的过程中 具体细节、问题&#xff1a; &#xff08;1&#xff09;&#xff1a;关于写Get_next函数的标题&#xff1a; 现象&#xff1a; PPT上写的是&#xff1a; void get_next(SString T, int &next[]) 然而并不能运行&#xff0c;而当我们去掉了引用符号&…

记录踩过的坑-Git

Git命令克隆很慢原命令&#xff1a;git clone -b r1.13.0 https://github.com/tensorflow/models.git现在替换为&#xff1a;git clone -b r1.13.0 https://github.com.cnpmjs.org/tensorflow/models.git也就是把原 URL 中的 github.com 替换为 github.com.cnpmjs.org&#xff…

设计模式第9式:迭代器模式

前言 我们有很多种方法可以把对象集中到一个集合中&#xff0c;比如列表、堆栈、散列表中。每种集合都有自己的特点和使用时机&#xff0c;但都有一个共同的需求&#xff1a;用户想要遍历这些对象。同时我们并不想用户看到集合的实现&#xff0c;本文将讲解如何让用户遍历对象…

JVM垃圾回收器详解

垃圾收集器没有在规范中进行过多的规定&#xff0c;可以由不同的厂商、不同版本的JVM来实现。由于JDK的版本处于高速迭代过程中&#xff0c;因此Java发展至今已经衍生了众多的GC版本。从不同角度分析垃圾收集器&#xff0c;可以将GC分为不同的类型。1、垃圾回收器分类1.1、按线…

国际安全领域顶会NDSS 2023录稿整理 (下)

隐私计算研习社 NDSS是网络和系统安全领域的四大顶级国际学术会议&#xff08;BIG4&#xff09;之一&#xff0c;第三十届会议于2023年2月27日到3月3日&#xff0c;在美国圣迭戈举办。本文将接着整理剩余论文&#xff0c;并对论文进行分类&#xff0c;感兴趣的小伙伴可以访问论…

【Linux】信号+再谈进程地址空间

目录 一、Linux中的信号 1、Linux中的信号 2、进程对信号的处理 3、信号的释义 二、信号的捕捉 1、信号的捕捉signal() 2、信号的捕捉sigaction() 三、信号如何产生&#xff1f; 1、kill()用户调用kill向操作系统发送信号 通过命令行参数模仿写一个kill命令 2、rais…

pinctrl和gpio子系统

一、pinctrl子系统简介Linux驱动讲究驱动分离与分层&#xff0c;pinctrl和gpio子系统就是驱动分离与分层思想下的产物&#xff0c;pinctrl子系统主要工作内容如下&#xff1a;获取设备树中的pin信息根据获取到的pin信息来设置pin的复用功能根据获取到的pin信息来设置pin的电气属…

Day914.安全认证架构演进:单块阶段 -SpringBoot与K8s云原生微服务实践

安全认证架构演进&#xff1a;单块阶段 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于安全认证架构演进&#xff1a;单块阶段的内容。 讲到安全认证的内容&#xff0c;就必然会提到两个点&#xff1a;认证 和 授权。 认证&#xff1a;我是谁授权&#xff1a;我能…

Spring中的事务@Transactional

Transactional可以添加在方法上 添加在方法上时&#xff0c;表示该方法出现了异常或者报错&#xff0c;而导致之前数据库没有进行回滚事件&#xff0c;也就是说如果在方法中&#xff0c;有报错&#xff0c;但是添加了Transactional 则会开始回滚。 Transactional 在异常被捕获…

剑指 Offer 29. 顺时针打印矩阵

剑指 Offer 29. 顺时针打印矩阵 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 输入一个矩阵&#xff0c;按照从外向里以顺时针的顺序依次打印出每一个数字。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2…

【OpenCV技能树】——OpenCV基础

前言&#xff1a; &#x1f60a;&#x1f60a;&#x1f60a;欢迎来到本博客&#x1f60a;&#x1f60a;&#x1f60a; 目前正在进行 OpenCV技能树的学习&#xff0c;OpenCV是学习图像处理理论知识比较好的一个途径&#xff0c;至少比看书本来得实在。本专栏文章主要记录学习Op…