The constraint that n <= 20 is basically a hint screaming bitmask DP at you.
Model each word as a bitmask of its characters, discarding any word with duplicate characters. Then use dynamic programming over subsets of the 26-letter alphabet to find the maximum total characters achievable by combining disjoint masks, and reconstruct the chosen words.
Pro tip: Mention that you can prune the DP by only considering masks that are subsets of the current state, and that using a hash map for DP states can be more memory-efficient than a full array when the number of reachable states is small.
For each word, compute a 26-bit integer where each bit represents a distinct character. If a word has any duplicate character, discard it immediately.
Let dp[mask] store the maximum number of distinct characters achievable using a subset of words whose combined character set is exactly mask. Initialize dp[0] = 0 and others to -1. For each word mask w, update dp[new_mask] = max(dp[new_mask], dp[mask] + popcount(w)) for all masks disjoint from w.
Process words one by one, updating the DP table in a way that avoids using the same word multiple times (e.g., iterate masks in descending order or use a new table per word).
After processing all words, find the mask with the maximum dp value. To reconstruct the chosen words, store parent pointers or backtrack by checking which word led to the optimal state.
Output the list of words corresponding to the optimal mask. If multiple optimal subsets exist, any one is acceptable.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.