最大兼容性评分和-c语言

最大兼容性评分和

有一份由 n 个问题组成的调查问卷,每个问题的答案要么是 0(no,否),要么是 1(yes,是)。

这份调查问卷被分发给 m 名学生和 m 名导师,学生和导师的编号都是从 0 到 m - 1 。学生的答案用一个二维整数数组 students 表示,其中 students[i] 是一个整数数组,包含第 i 名学生对调查问卷给出的答案(下标从 0 开始)。导师的答案用一个二维整数数组 mentors 表示,其中 mentors[j] 是一个整数数组,包含第 j 名导师对调查问卷给出的答案(下标从 0 开始)。

每个学生都会被分配给 一名 导师,而每位导师也会分配到 一名 学生。配对的学生与导师之间的兼容性评分等于学生和导师答案相同的次数。

例如,学生答案为[1, 0, 1] 而导师答案为 [0, 0, 1] ,那么他们的兼容性评分为 2 ,因为只有第二个和第三个答案相同。

请你找出最优的学生与导师的配对方案,以 最大程度上 提高 兼容性评分和 。

给你 students 和 mentors ,返回可以得到的 最大兼容性评分和 。

示例 1:

输入:students = [[1,1,0],[1,0,1],[0,0,1]], mentors = [[1,0,0],[0,0,1],[1,1,0]]
输出:8
解释:按下述方式分配学生和导师:

  • 学生 0 分配给导师 2 ,兼容性评分为 3 。
  • 学生 1 分配给导师 0 ,兼容性评分为 2 。
  • 学生 2 分配给导师 1 ,兼容性评分为 3 。
    最大兼容性评分和为 3 + 2 + 3 = 8 。

示例 2:

输入:students = [[0,0],[0,0],[0,0]], mentors = [[1,1],[1,1],[1,1]]
输出:0
解释:任意学生与导师配对的兼容性评分都是 0 。

这一题,其实,我们就是找老师和学生配对的最优和
那么这题最好的做法就是枚举排列组合,然后求评分和的最大值,最难的是,我们如何通过c语言进行排列组合的枚举,那么c语言只能通过递归法仅仅枚举,使用其他方法将消耗大量的内存,超过指数级,大家可以通过这个方法学习一下,如何进行c语言的排列组合枚举:
代码如下:

#define NUM_MAX 8

int g_max_compatibility_sum;
int g_book[NUM_MAX]; // 标记路径是否走过

// dfs思想,对导师进行全排列
void dfs(int step, int **students, int **mentors, int mentorsSize, int *mentorsColSize, int **a, int *g_book)
{
    int i, j;
    
    // 到达终点,计算兼容性评分和,并更新最大值
    if (step == mentorsSize) {
        int temp_sum = 0;
        for (i = 0; i < mentorsSize; i++) {
            for (j = 0; j < mentorsColSize[i]; j++) {
                if (students[i][j] == a[i][j]) {
                    temp_sum++;
                }
            }
        }
        g_max_compatibility_sum = fmax(g_max_compatibility_sum, temp_sum);
        
        return;
    }
    
    // 对可选择的路径进行遍历
    for (i = 0; i < mentorsSize; i++) {
        if (g_book[i] == 0) {
            // 做选择
            memcpy(a[step], mentors[i], mentorsColSize[i] * sizeof(int));
            g_book[i] = 1;
            dfs(step + 1, students, mentors, mentorsSize, mentorsColSize, a, g_book);
            // 撤销选择
            g_book[i] = 0;
        }
    }
    
    return;
}

int maxCompatibilitySum(int **students, int studentsSize, int *studentsColSize, int **mentors, int mentorsSize, int *mentorsColSize)
{
    int i;
    g_max_compatibility_sum = 0;
    memset(g_book, 0, sizeof(g_book));
    
    // a用来临时存储每一次排列的情况
    int **a = (int **)malloc(mentorsSize * sizeof(int *));
    for (i = 0; i < mentorsSize; i++) {
        a[i] = (int *)malloc(mentorsColSize[i] * sizeof(int));
        memset(a[i], 0, mentorsColSize[i] * sizeof(int));
    }
    
    dfs(0, students, mentors, mentorsSize, mentorsColSize, a, g_book);
    
    return g_max_compatibility_sum;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值