首页 > 其他分享 >1947. 最大兼容性评分和

1947. 最大兼容性评分和

时间:2022-10-29 10:23:50浏览次数:96  
标签:兼容性 评分 List 枚举 1947 students range 数组

题目描述

给了一个学生数组和老师数组,数组长度都是m
每个数组元素ei又是个数组,有k个元素,某个数组其中学生和老师的对应元素一样的个数定义为兼容性评分
问怎么匹配老师和学生的数组,让兼容性评分最大?

f1-状态压缩+动态规格

基本分析

  1. 这种两个等长数组匹配的题目怎么考虑?因为可以换顺序,固定一个不动,另一个枚举状态
  2. 这个得分的转移好些吗?对某个学生i,老师j的兼容性直接预处理就行,不要想的太复杂(比如异或)
  3. 剩下咋处理?常规的枚举老师状态,枚举最后一个老师位置i,之前的状态就是mask-1<<i,转移时择大取f[masx]

代码

class Solution:
    def maxCompatibilitySum(self, students: List[List[int]], mentors: List[List[int]]) -> int:
        # 预处理11对应的得分
        m = len(students)
        n = len(students[0]) 
        cnt = [[0]*m for _ in range(m)]
        for i in range(m):
            for j in range(m):
                c = 0
                for k in range(n):
                    if students[i][k] == mentors[j][k]:
                        c += 1
                cnt[i][j] = c
        
        nmask = 1<<m
        f = [0] * nmask
        for mask in range(nmask):
            c = bin(mask).count('1')
            for i in range(m):
                if mask &(1<<i):
                    f[mask] = max(f[mask], f[mask-(1<<i)] + cnt[c-1][i])
        
        return f[-1]

复杂度

时间:\(预处理得分的一一对应关系O(n \cdot m^2), 状态及转移O(m \cdot 2^m)\)
空间:\(存对应得分O(m^2), 存dp结果2^m\)

总结

这个转移关系很好想,在处理兼容性得分的时候,一定要有预处理的思路。最开始想着能不能用异或实现,但是001 和001这种情况的异或不好处理,不如直接枚举处理简单
然后是转移的思路:这个mask不管顺序,只管选没选,然后从选了的人里面枚举最后一个,那么之前的状态就有了,并且肯定是算过的,而且对应的累加关系也是有的,肯定是第c个学生和枚举的最后的老师。

标签:兼容性,评分,List,枚举,1947,students,range,数组
From: https://www.cnblogs.com/zk-icewall/p/16838155.html

相关文章