public class Solution { private int[] freqs; private void SetFreqs(char[] letters) { freqs = new int[26]; foreach (char c in letters) { ++freqs[c - 'a']; } } private int maxScore; private int currentScore; private string[] words; private int[] score; private void check(int i) { if (i >= words.Length) { maxScore = Math.Max(maxScore, currentScore); return; } // Skipping the current word check(i + 1); // Try to add word int j; for (j = 0; j < words[i].Length; ++j) { var c = words[i][j] - 'a'; --freqs[c]; currentScore += score[c]; if (freqs[c] < 0) { break; } } // Means we were able to use all letters from the word if (j == words[i].Length) { check(i + 1); } // Revert the changes for (j = Math.Min(j, words[i].Length - 1); j >= 0; --j) { var c = words[i][j] - 'a'; ++freqs[c]; currentScore -= score[c]; } } public int MaxScoreWords(string[] words, char[] letters, int[] score) { SetFreqs(letters); maxScore = 0; currentScore = 0; this.words = words; this.score = score; check(0); return maxScore; } }