首页 > 其他分享 >1255. 得分最高的单词集合

1255. 得分最高的单词集合

时间:2022-10-20 16:33:21浏览次数:59  
标签:得分 ch letters 单词 枚举 1255 words

题目描述

给一个单词表words, 一个字母表letters
当用letters中的字母可以拼出words中的某个单词时,可以获得得分,
得分是按照字母来算的,每个字母得分在score数组中
提示:

  • 单词表长度不大于14
  • words和letters中只包含小写字母
  • words中每个单词只能使用一次
  • 每个字母的使用不能超过其在letter中的个数
f1-枚举子集+状态压缩

基本分析

  1. 由于字母不能超过对应的个数,怎么判断需要用当前字母合成哪些单词并计算得分?没有捷径,就是枚举凑哪些单词出来
  2. 怎么枚举凑哪些单词?用一个二进制数来表示状态,state从低位到高位分别表示第i个word是不是凑出来
  3. 怎么判断当前方案是不是可行?
    • 需要定义一个字典,表示当前状态使用的字符的情况,如果超过了,就返回0;如果没有超过就计算得分
    • 怎么维护这个字典?i在(0,n)中遍历,如果当前位i是1,就把words[i]对应的字符累加进去
    • 怎么统计这个状态对应的得分?遍历d,对每个ch-v,分别计算得分并最终求和
  4. 怎么获取最终结果?
    枚举每个结果,取最大值

代码

class Solution:
    def maxScoreWords(self, words: List[str], letters: List[str], score: List[int]) -> int:
        # 统计每个单词对应的字母情况
        words_cnt = [Counter(word) for word in letters]
        letters_cnt = Counter(letters)

        n = len(words)
        @cache
        def dfs(state):
            d = dict()
            for i in range(n):
                if state >>i == 1: # 包含第i word
                    for ch, v in words_cnt[i].items():
                        d[ch] = d.get(ch, 0) + v
                        if d[ch] > letters_cnt[ch]:
                            return 0
            
            ans = sum([score[ord(ch)-ord('a')] * v for ch, v in d.items()])
            return ans
        
        ans = max(dfs(i) for i in range(1, 1<<n))
        
        return ans

复杂度

时间:待确定
空间:待确定

总结

  1. 这里每个单词都有两种可能,枚举了0-1<<n种可能
  2. 对每种可能计算能不能满足要求,能满足的计算得分
  3. 最终每种的得分取最大
  4. 还有比较快的f2-记忆化搜索+状态压缩的做法,待更新

标签:得分,ch,letters,单词,枚举,1255,words
From: https://www.cnblogs.com/zk-icewall/p/16810357.html

相关文章