from collections import Counter
class Solution:
def maxScoreWords(self, words, letters, score):
letter_count = Counter(letters)
n = len(words)
word_counts = [Counter(word) for word in words]
word_scores = [sum(score[ord(c)-ord('a')]*cnt for c, cnt in wc.items()) for wc in word_counts]
self.ans = 0
def backtrack(i, curr_score, curr_count):
if i == n:
self.ans = max(self.ans, curr_score)
return
# Try to skip the current word
backtrack(i+1, curr_score, curr_count)
# Try to use the current word if possible
can_use = True
for c in word_counts[i]:
if curr_count[c] < word_counts[i][c]:
can_use = False
break
if can_use:
for c in word_counts[i]:
curr_count[c] -= word_counts[i][c]
backtrack(i+1, curr_score + word_scores[i], curr_count)
for c in word_counts[i]:
curr_count[c] += word_counts[i][c]
backtrack(0, 0, letter_count.copy())
return self.ans
class Solution {
public:
int maxScoreWords(vector<string>& words, vector<char>& letters, vector<int>& score) {
vector<int> letterCount(26, 0);
for (char c : letters) letterCount[c - 'a']++;
int n = words.size();
int ans = 0;
function<void(int, int, vector<int>&)> backtrack = [&](int i, int currScore, vector<int>& currCount) {
if (i == n) {
ans = max(ans, currScore);
return;
}
// Skip current word
backtrack(i + 1, currScore, currCount);
// Try to use current word
vector<int> wordCount(26, 0);
for (char c : words[i]) wordCount[c - 'a']++;
bool canUse = true;
for (int c = 0; c < 26; ++c) {
if (wordCount[c] > currCount[c]) {
canUse = false;
break;
}
}
if (canUse) {
for (int c = 0; c < 26; ++c) currCount[c] -= wordCount[c];
int wordScore = 0;
for (int c = 0; c < 26; ++c) wordScore += wordCount[c] * score[c];
backtrack(i + 1, currScore + wordScore, currCount);
for (int c = 0; c < 26; ++c) currCount[c] += wordCount[c];
}
};
backtrack(0, 0, letterCount);
return ans;
}
};
class Solution {
int ans = 0;
public int maxScoreWords(String[] words, char[] letters, int[] score) {
int[] letterCount = new int[26];
for (char c : letters) letterCount[c - 'a']++;
backtrack(words, score, letterCount, 0, 0);
return ans;
}
private void backtrack(String[] words, int[] score, int[] currCount, int i, int currScore) {
if (i == words.length) {
ans = Math.max(ans, currScore);
return;
}
// Skip current word
backtrack(words, score, currCount, i + 1, currScore);
// Try to use current word
int[] wordCount = new int[26];
for (char c : words[i].toCharArray()) wordCount[c - 'a']++;
boolean canUse = true;
for (int c = 0; c < 26; ++c) {
if (wordCount[c] > currCount[c]) {
canUse = false;
break;
}
}
if (canUse) {
for (int c = 0; c < 26; ++c) currCount[c] -= wordCount[c];
int wordScore = 0;
for (int c = 0; c < 26; ++c) wordScore += wordCount[c] * score[c];
backtrack(words, score, currCount, i + 1, currScore + wordScore);
for (int c = 0; c < 26; ++c) currCount[c] += wordCount[c];
}
}
}
var maxScoreWords = function(words, letters, score) {
let letterCount = Array(26).fill(0);
for (let c of letters) letterCount[c.charCodeAt(0) - 97]++;
let n = words.length;
let ans = 0;
function backtrack(i, currScore, currCount) {
if (i === n) {
ans = Math.max(ans, currScore);
return;
}
// Skip current word
backtrack(i + 1, currScore, currCount);
// Try to use current word
let wordCount = Array(26).fill(0);
for (let c of words[i]) wordCount[c.charCodeAt(0) - 97]++;
let canUse = true;
for (let c = 0; c < 26; ++c) {
if (wordCount[c] > currCount[c]) {
canUse = false;
break;
}
}
if (canUse) {
for (let c = 0; c < 26; ++c) currCount[c] -= wordCount[c];
let wordScore = 0;
for (let c = 0; c < 26; ++c) wordScore += wordCount[c] * score[c];
backtrack(i + 1, currScore + wordScore, currCount);
for (let c = 0; c < 26; ++c) currCount[c] += wordCount[c];
}
}
backtrack(0, 0, letterCount.slice());
return ans;
};
words
, a list of available letters letters
, and a list of scores score
where score[i]
is the score for the i
-th letter of the alphabet, your task is to find the maximum score you can get by selecting a subset of words
and forming them using the letters in letters
(each letter can be used at most once). The score for each word is the sum of scores for each letter in the word. You cannot reuse letters across words, and you can use each word at most once.
words = ["dog", "cat", "dad", "good"]
, letters = ["a","a","c","d","d","g","o","o"]
, and score
assigns 1 to all letters for simplicity.