zoukankan      html  css  js  c++  java
  • Leetcode: 1434. Number of Ways to Wear Different Hats to Each Other

    Descpition

    There are n people and 40 types of hats labeled from 1 to 40.
    Given a list of list of integers hats, where hats[i] is a list of all hats preferred by the i-th person.
    Return the number of ways that the n people wear different hats to each other.
    Since the answer may be too large, return it modulo 10^9 + 7.
    

    Example

    Input: hats = [[1,2,3],[2,3,5,6],[1,3,7,9],[1,8,9],[2,5,7]]
    Output: 111
    

    Note

    n == hats.length
    1 <= n <= 10
    1 <= hats[i].length <= 40
    1 <= hats[i][j] <= 40
    hats[i] contains a list of unique integers.
    

    分析

         本题需要用状态压缩来实现,一开始希望用 dict 来存储状态以减少存储空间和计算次数。但是事与愿违。
    后面改用数组来做存储
    

    code

    TLE 版本
    
    class Solution(object):
        def _do(self, hats):
            hat = 0
            for i in hats:
                for j in i:
                    hat |= (1<<(j-1))
    
            dp = [{} for _ in range(len(hats))]
            bitS = lambda x: 1 << (x-1)
    
            for v in hats[0]:
                dp[0][hat ^ bitS(v)] = 1
    
            for level in range(1, len(hats)):  # 每次都会计算满足 people[i] 帽子方案,等所有 people 都有帽子戴后返回所有值
               for v in hats[level]:
                   for k in dp[level-1]:
                       t, nb = k & bitS(v), k ^ bitS(v)
                       if t == 0:
                           continue
                       dp[level][nb] = (dp[level].get(nb, 0) + dp[level-1][k])%1000000007
             
            return sum([i for i in dp[-1].values()])%1000000007
    
        def do(self, hats):
            print(self._do(hats))
    
    
    if __name__ == '__main__':
        s = Solution()
    
    AC 版本
    class Solution(object):
        def _do(self, hats):
            hat_set, hat_sorted = set(), []
            for i, v in enumerate(hats):
                hat_set |= set(v)
    
            hat_sorted = sorted(list(hat_set))
            dp = [[0 for _ in range(0, 1<<len(hats))] for _ in range(len(hat_sorted))]
    
            bitS = lambda x: 1 << (x-1)
    
            for i, v in enumerate(hats):
                if hat_sorted[0] in v:
                    dp[0][bitS(i+1)] = 1
    
            for level in range(1, len(hat_sorted)):  # 每次都会计算 hat_sorted[i] 已经满足了哪些人的戴帽子需求
                for person in range(0, len(hats)):
                    if hat_sorted[level] not in hats[person]:
                        continue
    
                    dp[level][bitS(person+1)] = 1
    
                    for i, v in enumerate(dp[level-1]):
                        if i & bitS(person+1) != 0:
                            continue
                        dp[level][i | bitS(person+1)] += v
    
                for i, v in enumerate(dp[level-1]):  # 不用当前帽子时的方案
                    dp[level][i] += dp[level-1][i]
            return dp
    
        def do(self, hats):
            print(self._do(hats))
    
    
    if __name__ == '__main__':
        s = Solution()
        s.do([[3,2,1],[2,3]])
    
    

    总结

    • 思路很简单,就是一道普通的状态压缩 dp。但是选择不用的事物作为 dp 压缩会有很大不同的结果
    Runtime: 472 ms, faster than 54.46% of Python online submissions for Number of Ways to Wear Different Hats to Each Other.
    Memory Usage: 13.7 MB, less than 61.46% of Python online submissions for Number of Ways to Wear Different Hats to Each Other.
    
  • 相关阅读:
    python 读取excel表格中的数据
    python 安装 pip 报错解决方案
    HDU-1150-MachineSchedule(二分图匹配)
    POJ-3177-RedundantPaths(边联通分量,缩点)
    POJ-3352-RoadConstruction(边双联通分量,缩点)
    F-三生三世
    D-温暖的签到题
    C-晾衣服
    A-坐飞机
    POJ-2777-CountColor(线段树,位运算)
  • 原文地址:https://www.cnblogs.com/tmortred/p/13191383.html
Copyright © 2011-2022 走看看