You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效生成最优字母组合以最大化Scrabble得分(基于单词长度)

高效求解Scrabble最大得分组合方案

核心思路

放弃生成全排列/全组合的低效方式,改用字母频率统计+字典预处理+回溯剪枝的策略,从得分优先级和字母可用性入手,大幅缩小搜索范围。

具体实现步骤

1. 字典预处理与优先级排序

  • 先对Scrabble字典做筛选和排序,只保留长度4+的有效单词;
  • 按单位字母得分从高到低排序(优先级越高越先尝试):
    • 4-9字母单词:得分公式为(长度-3)*5,单位得分为5*(长度-3)/长度,计算后优先级为:9字母(30分,单位3.33)>8字母(25分,3.125)>...>4字母(5分,1.25);
    • ≥10字母单词:固定30分,单位得分为30/长度,10字母单词(单位3)优先级高于更长的同得分单词;
  • 将每个单词转换为collections.Counter对象(记录字母频率),方便后续快速校验字母是否足够。

2. 输入字母频率统计

把给定的36个字母转换成Counter对象,后续每次选中单词后,直接用Counter减法更新剩余字母的频率,避免重复使用同一字母。

3. 带剪枝的回溯搜索

按预处理好的优先级顺序尝试单词,递归搜索最优组合,同时加入剪枝条件减少无效计算:

  • 剪枝条件1:剩余字母总数不足4时,无法组成有效单词,直接终止当前分支;
  • 剪枝条件2:当前已得分数 + 剩余字母能组成的最大可能得分 ≤ 已找到的最优得分时,停止探索该分支(提前计算剩余字母的最大可能得分:优先按9字母单词累加,剩余不足9的部分若≥4则按对应规则计算,同时对比≥10字母的单单词得分);
  • 每次选中单词前,先校验剩余字母的频率是否覆盖该单词的字母需求,满足则更新剩余字母和当前得分,继续递归。

4. 额外优化技巧

  • 字典去重:移除字母组合完全相同的单词(如"listen"和"silent",得分一致,留一个即可);
  • 提前预计算所有单词的得分和Counter对象,避免递归中重复计算;
  • 用全局变量或类成员存储当前最优得分和组合,减少参数传递开销。

示例代码片段

from collections import Counter

# 预处理Scrabble字典
def preprocess_dict(word_list):
    valid_words = []
    for word in word_list:
        word_len = len(word)
        if word_len < 4:
            continue
        # 计算单词得分
        if 4 <= word_len <= 9:
            score = (word_len - 3) * 5
        else:
            score = 30
        # 计算单位字母得分,用于排序(得分效率越高越靠前)
        unit_score = score / word_len
        # 存储负单位分(方便升序排序后取优先级高的在前)、得分、字母计数器、单词本身
        valid_words.append((-unit_score, score, Counter(word), word))
    # 按单位得分从高到低排序
    valid_words.sort()
    # 整理成(得分, 字母计数器, 单词)的列表
    return [(score, cnt, word) for (_, score, cnt, word) in valid_words]

# 回溯搜索最优组合
max_total_score = 0
best_word_comb = []

def backtrack(remaining_letters, current_score, current_words, processed_words):
    global max_total_score, best_word_comb
    # 更新最优解
    if current_score > max_total_score:
        max_total_score = current_score
        best_word_comb = current_words.copy()
    # 剪枝:剩余字母不够组成最小有效单词
    total_remaining = sum(remaining_letters.values())
    if total_remaining < 4:
        return
    # 计算剩余字母能达到的最大可能得分
    max_possible = 0
    temp = total_remaining
    # 优先按9字母单词计算最大得分
    while temp >= 9:
        max_possible += 30
        temp -= 9
    if temp >= 4:
        max_possible += (temp - 3) * 5
    # 对比剩余字母≥10时的单单词得分(可能比拆分多个单词更高)
    if total_remaining >= 10:
        max_possible = max(max_possible, 30)
    # 剪枝:当前分支不可能超过已有最优得分,直接终止
    if current_score + max_possible <= max_total_score:
        return
    # 遍历优先级排序后的单词
    for score, word_cnt, word in processed_words:
        # 检查剩余字母是否满足单词需求
        if all(remaining_letters[char] >= word_cnt[char] for char in word_cnt):
            # 更新剩余字母
            new_remaining = remaining_letters - word_cnt
            current_words.append(word)
            backtrack(new_remaining, current_score + score, current_words, processed_words)
            current_words.pop()

# 用法示例
# 假设这里是你的Scrabble字典单词列表,实际需替换为完整字典
scrabble_dict = ["apple", "banana", "computer", "programming"]
input_letters = "abcdefghijklmnopqrstuvwxyzabcdefghij"  # 36个字母的输入字符串
remaining_counter = Counter(input_letters)
processed_words = preprocess_dict(scrabble_dict)

# 启动搜索
backtrack(remaining_counter, 0, [], processed_words)

print(f"最大得分: {max_total_score}")
print(f"最优单词组合: {best_word_comb}")

方案优势

  • 完全规避了36!排列或全组合的爆炸式计算,只聚焦有效单词;
  • 优先级排序让算法先尝试得分效率最高的单词,能快速找到较优解,进而更早触发剪枝,减少无效分支;
  • 基于字母频率的比对和更新,比逐个字母校验效率提升明显。

内容的提问来源于stack exchange,提问作者George Cheng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:00:48