1255. Maximum Score Words Formed by Letters
Given a list of words, list of single letters (might be repeating) and score of every character.
Return the maximum score of any valid set of words formed by using the given letters (wordsi cannot be used two or more times).
It is not necessary to use all characters in letters and each letter can only be used once. Score of letters 'a', 'b', 'c', ... ,'z' is given by score0, score1, ... , score25 respectively.
Example 1:
Input: words = "dog","cat","dad","good", letters = "a","a","c","d","d","d","g","o","o", score = 1,0,9,5,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0
Output: 23
Explanation:
Score a=1, c=9, d=5, g=3, o=2
Given letters, we can form the words "dad" (5+1+5) and "good" (3+2+2+5) with a score of 23.
Words "dad" and "dog" only get a score of 21.
Example 2:
Input: words = "xxxz","ax","bx","cx", letters = "z","a","b","c","x","x","x", score = 4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,10
Output: 27
Explanation:
Score a=4, b=4, c=4, x=5, z=10
Given letters, we can form the words "ax" (4+5), "bx" (4+5) and "cx" (4+5) with a score of 27.
Word "xxxz" only get a score of 25.
Example 3:
Input: words = "leetcode", letters = "l","e","t","c","o","d", score = 0,0,1,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0
Output: 0
Explanation:
Letter "e" can only be used once.
Constraints:
- 1 <= words.length <= 14
- 1 <= wordsi.length <= 15
- 1 <= letters.length <= 100
- lettersi.length == 1
- score.length == 26
- 0 <= scorei <= 10
- wordsi, lettersi contains only lower case English letters.
From: LeetCode
Link: 1255. Maximum Score Words Formed by Letters
Solution:
Ideas:
DFS/backtracking. For each word, choose skip or take. Take only if enough letters remain. Since wordsSize <= 14, this 2^n solution is accepted.
Code:
c
int dfs(int idx, char** words, int wordsSize, int cnt[26], int* score) {
if (idx == wordsSize) return 0;
// Option 1: skip this word
int best = dfs(idx + 1, words, wordsSize, cnt, score);
// Option 2: use this word if possible
int need[26] = {0};
int wordScore = 0;
for (int i = 0; words[idx][i]; i++) {
int c = words[idx][i] - 'a';
need[c]++;
wordScore += score[c];
}
int ok = 1;
for (int i = 0; i < 26; i++) {
if (need[i] > cnt[i]) {
ok = 0;
break;
}
}
if (ok) {
for (int i = 0; i < 26; i++) cnt[i] -= need[i];
int take = wordScore + dfs(idx + 1, words, wordsSize, cnt, score);
if (take > best) best = take;
for (int i = 0; i < 26; i++) cnt[i] += need[i];
}
return best;
}
int maxScoreWords(char** words, int wordsSize, char* letters, int lettersSize, int* score, int scoreSize) {
int cnt[26] = {0};
for (int i = 0; i < lettersSize; i++) {
cnt[letters[i] - 'a']++;
}
return dfs(0, words, wordsSize, cnt, score);
}