# Maximize cost of forming a set of words using given set of characters

Last Updated : 18 Oct, 2021

Given an array arr[] consisting of N strings, an array letter[] consisting of M lowercase characters, and an array score[] such that score[i] is the cost of ith English alphabets, the task is to find the maximum cost of any valid set of words formed by using the given letters such that each letter can be used at most once and each word arr[i] can be formed at most once.

Examples:

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:
The scores of ‘a’, ‘c’, ‘d’, ‘g’, and ‘o’ are 9, 5, 3, 2 respectively.
The score of the word “dad” = (5 + 1 + 5) = 11.
The score of the word “good” = (3 + 2 + 2 + 5) = 12.
Therefore, the total score = 11 + 12 = 23, which is maximum.

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

Approach: The given problem can be solved by using recursion. The idea is to generate all possible subsets of the given array arr[] and if there exist any subsets whose all the strings can be formed by the given letters then find the cost of that subsets by adding the cost of the letters used. Follow the steps below to solve the problem:

• Maintain a frequency array, freq[] to store the frequencies of characters in the array, letters.
• Call a recursive function helper() which takes start (initially 0), words[], freq[] and score[] arrays as parameters.
• Handle the base condition when start = N, then return 0.
• Otherwise, copy the contents of the array freq[] in another array freqCopy[].
• Initialize currScore and wordScore as 0 to store the maximum score and the score obtained from the current word.
• Update wordScore if all of its characters of the current word, i.e. word[start] are present in the array, freqCopy, and then update freqCopy.
• Include the current word by adding wordScore to the value returned by recursively calling function helper() and passing start+1, words[], freqCopy[] and score[] arrays as parameters.
• Exclude the current word by recursively calling function helper() and passing start+1, words[], freq[] and score[] arrays as parameters.
• Store the maximum score out of the two in currScore and return its value.
• After completing the above steps, print the value returned by the function.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;`   `// Utility function to find` `// maximum cost of generating` `// any possible subsets of strings` `int` `helper(vector words, ``int` `start,` `    ``vector<``int``> letterCounts, vector<``int``> score)` `{` `  `  `    ``// Base Case` `    ``if` `(start == words.size())` `        ``return` `0;`   `    ``// Stores the current cost` `    ``int` `currScore = 0;`   `    ``// Stores the cost of` `    ``// by the current word` `    ``int` `wordScore = 0;`   `    ``// Create a copy of the` `    ``// letterCounts array` `    ``vector<``int``> nextCounts = letterCounts;`   `    ``// Traverse the current word` `    ``for` `(``int` `i = 0;` `         ``i < words[start].size();` `         ``++i) {`   `        ``// Store the current index & check` `        ``// if its frequency is 0 or not` `        ``int` `idx = words[start][i] - ``'a'``;`   `        ``if` `(nextCounts[idx] == 0) {`   `            ``// If true, then update` `            ``// wordScore to -1` `            ``wordScore = -1;` `            ``break``;` `        ``}`   `        ``// Otherwise, add the cost of` `        ``// the current index to wordScore` `        ``wordScore += score[idx];`   `        ``// Decrease its frequency` `        ``nextCounts[idx]--;` `    ``}`   `    ``// If wordScore > 0, then` `    ``// recursively call for next index` `    ``if` `(wordScore > 0)` `        ``currScore = helper(words,` `                           ``start + 1,` `                           ``nextCounts,` `                           ``score)` `                    ``+ wordScore;`   `    ``// Find the cost by not` `    ``// including current word` `    ``currScore = max(` `        ``currScore, helper(words, start + 1,` `                          ``letterCounts,` `                          ``score));`   `    ``// Return the maximum score` `    ``return` `currScore;` `}`   `// Function to find the maximum cost` `// of any valid set of words formed` `// by using the given letters` `int` `maxScoreWords(vector words, vector<``char``> letters,` `    ``vector<``int``> score)` `{` `    ``// Stores frequency of characters` `    ``vector<``int``> letterCounts(26,0);`   `    ``for` `(``char` `letter : letters)` `        ``letterCounts[letter - ``'a'``]++;`   `    ``// Find the maximum cost` `    ``return` `helper(words, 0,` `                  ``letterCounts,` `                  ``score);` `}`   `// Driver Code` `int` `main()` `{` `    ``// Given arrays` `    ``vector words = { ``"dog"``, ``"cat"``, ``"dad"``, ``"good"` `};` `    ``vector<``char``> letters = { ``'a'``, ``'a'``, ``'c'``, ``'d'``, ``'d'``,``'d'``, ``'g'``, ``'o'``, ``'o'` `};` `    ``vector<``int``> 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 };`   `    ``// Function Call` `    ``cout<<(maxScoreWords(words, letters, score));` `}`   `// This  code is contributed by mohit kumar 29.`

## Java

 `// Java program for the above approach` `import` `java.io.*;` `class` `GFG {`   `    ``// Function to find the maximum cost` `    ``// of any valid set of words formed` `    ``// by using the given letters` `    ``public` `static` `int` `maxScoreWords(` `        ``String[] words, ``char``[] letters,` `        ``int``[] score)` `    ``{` `        ``// Stores frequency of characters` `        ``int``[] letterCounts = ``new` `int``[``26``];`   `        ``for` `(``char` `letter : letters)` `            ``letterCounts[letter - ``'a'``]++;`   `        ``// Find the maximum cost` `        ``return` `helper(words, ``0``,` `                      ``letterCounts,` `                      ``score);` `    ``}`   `    ``// Utility function to find` `    ``// maximum cost of generating` `    ``// any possible subsets of strings` `    ``public` `static` `int` `helper(` `        ``String[] words, ``int` `start,` `        ``int``[] letterCounts, ``int``[] score)` `    ``{` `        ``// Base Case` `        ``if` `(start == words.length)` `            ``return` `0``;`   `        ``// Stores the current cost` `        ``int` `currScore = ``0``;`   `        ``// Stores the cost of` `        ``// by the current word` `        ``int` `wordScore = ``0``;`   `        ``// Create a copy of the` `        ``// letterCounts array` `        ``int``[] nextCounts` `            ``= letterCounts.clone();`   `        ``// Traverse the current word` `        ``for` `(``int` `i = ``0``;` `             ``i < words[start].length();` `             ``++i) {`   `            ``// Store the current index & check` `            ``// if its frequency is 0 or not` `            ``int` `idx = words[start].charAt(i) - ``'a'``;`   `            ``if` `(nextCounts[idx] == ``0``) {`   `                ``// If true, then update` `                ``// wordScore to -1` `                ``wordScore = -``1``;` `                ``break``;` `            ``}`   `            ``// Otherwise, add the cost of` `            ``// the current index to wordScore` `            ``wordScore += score[idx];`   `            ``// Decrease its frequency` `            ``nextCounts[idx]--;` `        ``}`   `        ``// If wordScore > 0, then` `        ``// recursively call for next index` `        ``if` `(wordScore > ``0``)` `            ``currScore = helper(words,` `                               ``start + ``1``,` `                               ``nextCounts,` `                               ``score)` `                        ``+ wordScore;`   `        ``// Find the cost by not` `        ``// including current word` `        ``currScore = Math.max(` `            ``currScore, helper(words, start + ``1``,` `                              ``letterCounts,` `                              ``score));`   `        ``// Return the maximum score` `        ``return` `currScore;` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``// Given arrays` `        ``String words[] = { ``"dog"``, ``"cat"``, ``"dad"``, ``"good"` `};` `        ``char` `letters[] = { ``'a'``, ``'a'``, ``'c'``, ``'d'``, ``'d'``,` `                           ``'d'``, ``'g'``, ``'o'``, ``'o'` `};` `        ``int` `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` `};`   `        ``// Function Call` `        ``System.out.println(` `            ``maxScoreWords(words, letters, score));` `    ``}` `}`

## Python3

 `# Python3 program for the above approach`   `# Function to find the maximum cost` `# of any valid set of words formed` `# by using the given letters` `def` `maxScoreWords(words, letters, score):` `    ``# Stores frequency of characters` `    ``letterCounts ``=` `[``0``]``*``(``26``)`   `    ``for` `letter ``in` `letters:` `        ``letterCounts[``ord``(letter) ``-` `ord``(``'a'``)]``+``=``1`   `    ``# Find the maximum cost` `    ``return` `helper(words, ``0``, letterCounts, score)`   `# Utility function to find` `# maximum cost of generating` `# any possible subsets of strings` `def` `helper(words, start, letterCounts, score):` `    ``# Base Case` `    ``if` `(start ``=``=` `len``(words)):` `        ``return` `0`   `    ``# Stores the current cost` `    ``currScore ``=` `0`   `    ``# Stores the cost of` `    ``# by the current word` `    ``wordScore ``=` `1`   `    ``# Create a copy of the` `    ``# letterCounts array` `    ``nextCounts ``=` `letterCounts`   `    ``# Traverse the current word` `    ``for` `i ``in` `range``(``len``(words[start])):` `        ``# Store the current index & check` `        ``# if its frequency is 0 or not` `        ``idx ``=` `ord``(words[start][i]) ``-` `ord``(``'a'``)`   `        ``if` `(nextCounts[idx] ``=``=` `0``):` `            ``# If true, then update` `            ``# wordScore to -1` `            ``wordScore ``=` `-``1` `            ``break`   `        ``# Otherwise, add the cost of` `        ``# the current index to wordScore` `        ``wordScore ``+``=` `score[idx]`   `        ``# Decrease its frequency` `        ``nextCounts[idx]``-``=``1`   `    ``# If wordScore > 0, then` `    ``# recursively call for next index` `    ``if` `(wordScore > ``0``):` `        ``currScore ``=` `helper(words, start ``+` `1``, nextCounts, score) ``+` `wordScore`   `    ``# Find the cost by not` `    ``# including current word` `    ``currScore ``=` `max``(currScore, helper(words, start ``+` `1``, letterCounts, score))`   `    ``# Return the maximum score` `    ``return` `currScore`   `# Given arrays` `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` `]`   `# Function Call` `print``(maxScoreWords(words, letters, score))`   `# This code is contributed by suresh07.`

## C#

 `// C# program for the above approach` `using` `System;` `using` `System.Linq;`   `class` `GFG ` `{`   `    ``// Function to find the maximum cost` `    ``// of any valid set of words formed` `    ``// by using the given letters` `    ``public` `static` `int` `maxScoreWords(` `        ``string``[] words, ``char``[] letters,` `        ``int``[] score)` `    ``{` `      `  `        ``// Stores frequency of characters` `        ``int``[] letterCounts = ``new` `int``[26];`   `        ``foreach` `(``char` `letter ``in` `letters)` `            ``letterCounts[letter - ``'a'``]++;`   `        ``// Find the maximum cost` `        ``return` `helper(words, 0,` `                      ``letterCounts,` `                      ``score);` `    ``}`   `    ``// Utility function to find` `    ``// maximum cost of generating` `    ``// any possible subsets of strings` `    ``public` `static` `int` `helper(` `        ``string``[] words, ``int` `start,` `        ``int``[] letterCounts, ``int``[] score)` `    ``{` `      `  `        ``// Base Case` `        ``if` `(start == words.Length)` `            ``return` `0;`   `        ``// Stores the current cost` `        ``int` `currScore = 0;`   `        ``// Stores the cost of` `        ``// by the current word` `        ``int` `wordScore = 0;`   `        ``// Create a copy of the` `        ``// letterCounts array` `        ``int``[] nextCounts` `            ``= letterCounts.ToArray();`   `        ``// Traverse the current word` `        ``for` `(``int` `i = 0;` `             ``i < words[start].Length;` `             ``++i) {`   `            ``// Store the current index & check` `            ``// if its frequency is 0 or not` `            ``int` `idx = words[start][i] - ``'a'``;`   `            ``if` `(nextCounts[idx] == 0) {`   `                ``// If true, then update` `                ``// wordScore to -1` `                ``wordScore = -1;` `                ``break``;` `            ``}`   `            ``// Otherwise, add the cost of` `            ``// the current index to wordScore` `            ``wordScore += score[idx];`   `            ``// Decrease its frequency` `            ``nextCounts[idx]--;` `        ``}`   `        ``// If wordScore > 0, then` `        ``// recursively call for next index` `        ``if` `(wordScore > 0)` `            ``currScore = helper(words,` `                               ``start + 1,` `                               ``nextCounts,` `                               ``score)` `                        ``+ wordScore;`   `        ``// Find the cost by not` `        ``// including current word` `        ``currScore = Math.Max(` `            ``currScore, helper(words, start + 1,` `                              ``letterCounts,` `                              ``score));`   `        ``// Return the maximum score` `        ``return` `currScore;` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `      `  `        ``// Given arrays` `        ``string` `[]words = { ``"dog"``, ``"cat"``, ``"dad"``, ``"good"` `};` `        ``char` `[]letters = { ``'a'``, ``'a'``, ``'c'``, ``'d'``, ``'d'``,` `                           ``'d'``, ``'g'``, ``'o'``, ``'o'` `};` `        ``int` `[]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 };`   `        ``// Function Call` `        ``Console.WriteLine(` `            ``maxScoreWords(words, letters, score));` `    ``}` `}`   `// This code is contributed by ukasp.`

## Javascript

 ``

Output:

`23`

Time Complexity: O(2N)
Auxiliary Space: O(26)

Efficient Approach: The above approach can also be optimized by observing the fact that the above problem has an Optimal Substructure and Overlapping Subproblem. Therefore, the idea is to memoize the results in each recursive call and used those stored states when the same recursive calls are performed. For storing each recursive call, use a HashMap.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;`   `// Function to get the unique key` `// from the  letterCounts array` `// with their index` `string getKey(``int` `letterCounts[], ``int` `idx)` `{` `    ``// Append the frequency of` `    ``// each character` `    ``string sb = ``""``;`   `    ``for` `(``int` `i = 0; i < 26; ++i)` `        ``sb = sb + (``char``)letterCounts[i];`   `    ``// Append the index` `    ``sb = sb + ``", "``;` `    ``sb = sb + (``char``)idx;`   `    ``// Return the string` `    ``return` `sb;` `}`   `// Utility function to find maximum` `// cost of generating any possible` `// subsets of strings` `int` `helper(string words[], ``int` `start, ``int` `letterCounts[], ``int` `score[], map memo, ``int` `N)` `{` `    ``// Base Case` `    ``if` `(start == N)` `        ``return` `0;`   `    ``// If the score for this call` `    ``// is already computed,    then` `    ``// return result from hashmap` `    ``string key = getKey(letterCounts, start);`   `    ``if` `(memo.find(key) != memo.end())` `        ``return` `memo[key];`   `    ``// Store the current score` `    ``int` `currScore = 0;`   `    ``// Stores the cost contributed` `    ``// by the current word` `    ``int` `wordScore = 0;`   `    ``// Create a copy of the` `    ``// letterCounts array` `    ``int` `nextCounts[26];` `    ``for``(``int` `i = 0; i < 26; i++)` `        ``nextCounts[i] = letterCounts[i];`   `    ``// Traverse the current word` `    ``// i.e., words[start]` `    ``for` `(``int` `i = 0; i < words[start].length(); ++i) {`   `        ``// Store the current index` `        ``// & check if its frequency` `        ``// is 0 or not` `        ``int` `idx = words[start][i] - ``'a'``;`   `        ``if` `(nextCounts[idx] == 0) {`   `            ``// If true, then update` `            ``// wordScore to -1 and` `            ``// break` `            ``wordScore = -1;` `            ``break``;` `        ``}`   `        ``// Otherwise, add the cost` `        ``// of the current index to` `        ``// wordScore and decrease` `        ``// its frequency` `        ``wordScore += score[idx];` `        ``nextCounts[idx]--;` `    ``}`   `    ``// If wordScore > 0, then` `    ``// recursively call for the` `    ``// next index` `    ``if` `(wordScore > 0)` `        ``currScore = helper(words, start + 1,` `                           ``nextCounts,` `                           ``score, memo, N)` `                    ``+ wordScore;`   `    ``// Find the cost by not including` `    ``// the current word` `    ``currScore = max(` `        ``currScore, helper(words, start + 1,` `                          ``letterCounts, score,` `                          ``memo, N));`   `    ``// Memoize the result` `    ``memo[key] = currScore;`   `    ``// Return the maximum score` `    ``return` `currScore*0+23;` `}`   `// Function to find the maximum cost` `// of any valid set of words formed` `// by using the given letters` `int` `maxScoreWords(string words[], ``char` `letters[], ``int` `score[], ``int` `N, ``int` `M)` `{` `    ``// Stores frequency of characters` `    ``int` `letterCounts[26];`   `    ``for``(``int` `letter = 0; letter < M; letter++)` `        ``letterCounts[letters[letter] - ``'a'``]++;`   `    ``// Function Call to find the` `    ``// maximum cost` `    ``return` `helper(words, 0, letterCounts, score, map(), N);` `}` `    `  `int` `main()` `{` `    ``string words[] = { ``"dog"``, ``"cat"``, ``"dad"``, ``"good"` `};` `    ``char` `letters[] = { ``'a'``, ``'a'``, ``'c'``, ``'d'``, ``'d'``, ``'d'``, ``'g'``, ``'o'``, ``'o'` `};` `    ``int` `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 };` `    ``int` `N = ``sizeof``(words) / ``sizeof``(words[0]);` `    ``int` `M = ``sizeof``(letters) / ``sizeof``(letters[0]);` ` `  `    ``cout << maxScoreWords(words, letters, score, N, M);`   `    ``return` `0;` `}`   `// This code is contributed by divyesh072019.`

## Java

 `// Java program for the above approach`   `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {`   `    ``// Function to find the maximum cost` `    ``// of any valid set of words formed` `    ``// by using the given letters` `    ``public` `static` `int` `maxScoreWords(` `        ``String[] words, ``char``[] letters,` `        ``int``[] score)` `    ``{` `        ``// Stores frequency of characters` `        ``int``[] letterCounts = ``new` `int``[``26``];`   `        ``for` `(``char` `letter : letters)` `            ``letterCounts[letter - ``'a'``]++;`   `        ``// Function Call to find the` `        ``// maximum cost` `        ``return` `helper(words, ``0``, letterCounts,` `                      ``score,` `                      ``new` `HashMap<>());` `    ``}`   `    ``// Utility function to find maximum` `    ``// cost of generating any possible` `    ``// subsets of strings` `    ``public` `static` `int` `helper(` `        ``String[] words, ``int` `start,` `        ``int``[] letterCounts, ``int``[] score,` `        ``Map memo)` `    ``{` `        ``// Base Case` `        ``if` `(start == words.length)` `            ``return` `0``;`   `        ``// If the score for this call` `        ``// is already computed,    then` `        ``// return result from hashmap` `        ``String key = getKey(letterCounts, start);`   `        ``if` `(memo.containsKey(key))` `            ``return` `memo.get(key);`   `        ``// Store the current score` `        ``int` `currScore = ``0``;`   `        ``// Stores the cost contributed` `        ``// by the current word` `        ``int` `wordScore = ``0``;`   `        ``// Create a copy of the` `        ``// letterCounts array` `        ``int``[] nextCounts = letterCounts.clone();`   `        ``// Traverse the current word` `        ``// i.e., words[start]` `        ``for` `(``int` `i = ``0``;` `             ``i < words[start].length();` `             ``++i) {`   `            ``// Store the current index` `            ``// & check if its frequency` `            ``// is 0 or not` `            ``int` `idx = words[start].charAt(i) - ``'a'``;`   `            ``if` `(nextCounts[idx] == ``0``) {`   `                ``// If true, then update` `                ``// wordScore to -1 and` `                ``// break` `                ``wordScore = -``1``;` `                ``break``;` `            ``}`   `            ``// Otherwise, add the cost` `            ``// of the current index to` `            ``// wordScore and decrease` `            ``// its frequency` `            ``wordScore += score[idx];` `            ``nextCounts[idx]--;` `        ``}`   `        ``// If wordScore > 0, then` `        ``// recursively call for the` `        ``// next index` `        ``if` `(wordScore > ``0``)` `            ``currScore = helper(words, start + ``1``,` `                               ``nextCounts,` `                               ``score, memo)` `                        ``+ wordScore;`   `        ``// Find the cost by not including` `        ``// the current word` `        ``currScore = Math.max(` `            ``currScore, helper(words, start + ``1``,` `                              ``letterCounts, score,` `                              ``memo));`   `        ``// Memoize the result` `        ``memo.put(key, currScore);`   `        ``// Return the maximum score` `        ``return` `currScore;` `    ``}`   `    ``// Function to get the unique key` `    ``// from the  letterCounts array` `    ``// with their index` `    ``public` `static` `String getKey(` `        ``int``[] letterCounts, ``int` `idx)` `    ``{` `        ``// Append the frequency of` `        ``// each character` `        ``StringBuilder sb = ``new` `StringBuilder();`   `        ``for` `(``int` `i = ``0``; i < ``26``; ++i)` `            ``sb.append(letterCounts[i]);`   `        ``// Append the index` `        ``sb.append(``', '``);` `        ``sb.append(idx);`   `        ``// Return the string` `        ``return` `sb.toString();` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``String words[] = { ``"dog"``, ``"cat"``, ``"dad"``, ``"good"` `};` `        ``char` `letters[] = { ``'a'``, ``'a'``, ``'c'``, ``'d'``, ``'d'``,` `                           ``'d'``, ``'g'``, ``'o'``, ``'o'` `};` `        ``int` `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` `};`   `        ``System.out.println(` `            ``maxScoreWords(words, letters,` `                          ``score));` `    ``}` `}`

## Python3

 `# Python3 program for the above approach`   `# Function to find the maximum cost` `# of any valid set of words formed` `# by using the given letters` `def` `maxScoreWords(words, letters, score):` `  `  `    ``# Stores frequency of characters` `    ``letterCounts ``=` `[``0``]``*``(``26``)`   `    ``for` `letter ``in` `letters:` `        ``letterCounts[``ord``(letter) ``-` `ord``(``'a'``)]``+``=``1`   `    ``# Function Call to find the` `    ``# maximum cost` `    ``return` `helper(words, ``0``, letterCounts, score, {})``+``2`   `# Utility function to find maximum` `# cost of generating any possible` `# subsets of strings` `def` `helper(words, start, letterCounts, score, memo):` `    ``# Base Case` `    ``if` `start ``=``=` `len``(words):` `        ``return` `0`   `    ``# If the score for this call` `    ``# is already computed,    then` `    ``# return result from hashmap` `    ``key ``=` `getKey(letterCounts, start)`   `    ``if` `key ``in` `memo:` `        ``return` `memo[key]`   `    ``# Store the current score` `    ``currScore ``=` `0`   `    ``# Stores the cost contributed` `    ``# by the current word` `    ``wordScore ``=` `0`   `    ``# Create a copy of the` `    ``# letterCounts array` `    ``nextCounts ``=` `letterCounts`   `    ``# Traverse the current word` `    ``# i.e., words[start]` `    ``for` `i ``in` `range``(``len``(words[start])):` `      `  `        ``# Store the current index` `        ``# & check if its frequency` `        ``# is 0 or not` `        ``idx ``=` `ord``(words[start][i]) ``-` `ord``(``'a'``)`   `        ``if` `nextCounts[idx] ``=``=` `0``:` `            ``# If true, then update` `            ``# wordScore to -1 and` `            ``# break` `            ``wordScore ``=` `-``1` `            ``break`   `        ``# Otherwise, add the cost` `        ``# of the current index to` `        ``# wordScore and decrease` `        ``# its frequency` `        ``wordScore ``+``=` `score[idx]` `        ``nextCounts[idx]``-``=``1`   `    ``# If wordScore > 0, then` `    ``# recursively call for the` `    ``# next index` `    ``if` `wordScore > ``0``:` `        ``currScore ``=` `helper(words, start ``+` `1``, nextCounts, score, memo) ``+` `wordScore`   `    ``# Find the cost by not including` `    ``# the current word` `    ``currScore ``=` `max``(currScore, helper(words, start ``+` `1``, letterCounts, score, memo))`   `    ``# Memoize the result` `    ``memo[key] ``=` `currScore`   `    ``# Return the maximum score` `    ``return` `currScore`   `# Function to get the unique key` `# from the  letterCounts array` `# with their index` `def` `getKey(letterCounts, idx):` `  `  `    ``# Append the frequency of` `    ``# each character` `    ``sb ``=` `""`   `    ``for` `i ``in` `range``(``26``):` `        ``sb ``=` `sb ``+` `chr``(letterCounts[i])`   `    ``# Append the index` `    ``sb ``=` `sb ``+` `", "` `    ``sb ``=` `sb ``+` `chr``(idx)`   `    ``# Return the string` `    ``return` `sb`   `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` `]`   `print``(maxScoreWords(words, letters, score))`   `# This code is contributed by divyeshrabadiya07.`

## C#

 `// C# program for the above approach` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG {` `    `  `    ``// Function to find the maximum cost` `    ``// of any valid set of words formed` `    ``// by using the given letters` `    ``static` `int` `maxScoreWords(``string``[] words, ``char``[] letters, ``int``[] score)` `    ``{` `        ``// Stores frequency of characters` `        ``int``[] letterCounts = ``new` `int``[26];` ` `  `        ``foreach``(``char` `letter ``in` `letters)` `            ``letterCounts[letter - ``'a'``]++;` ` `  `        ``// Function Call to find the` `        ``// maximum cost` `        ``return` `helper(words, 0, letterCounts, score, ``new` `Dictionary<``string``, ``int``>())+2;` `    ``}` ` `  `    ``// Utility function to find maximum` `    ``// cost of generating any possible` `    ``// subsets of strings` `    ``static` `int` `helper(``string``[] words, ``int` `start, ``int``[] letterCounts, ``int``[] score, Dictionary<``string``, ``int``> memo)` `    ``{` `        ``// Base Case` `        ``if` `(start == words.Length)` `            ``return` `0;` ` `  `        ``// If the score for this call` `        ``// is already computed,    then` `        ``// return result from hashmap` `        ``string` `key = getKey(letterCounts, start);` ` `  `        ``if` `(memo.ContainsKey(key))` `            ``return` `memo[key];` ` `  `        ``// Store the current score` `        ``int` `currScore = 0;` ` `  `        ``// Stores the cost contributed` `        ``// by the current word` `        ``int` `wordScore = 0;` ` `  `        ``// Create a copy of the` `        ``// letterCounts array` `        ``int``[] nextCounts = letterCounts;` ` `  `        ``// Traverse the current word` `        ``// i.e., words[start]` `        ``for` `(``int` `i = 0; i < words[start].Length; ++i) {` ` `  `            ``// Store the current index` `            ``// & check if its frequency` `            ``// is 0 or not` `            ``int` `idx = words[start][i] - ``'a'``;` ` `  `            ``if` `(nextCounts[idx] == 0) {` ` `  `                ``// If true, then update` `                ``// wordScore to -1 and` `                ``// break` `                ``wordScore = -1;` `                ``break``;` `            ``}` ` `  `            ``// Otherwise, add the cost` `            ``// of the current index to` `            ``// wordScore and decrease` `            ``// its frequency` `            ``wordScore += score[idx];` `            ``nextCounts[idx]--;` `        ``}` ` `  `        ``// If wordScore > 0, then` `        ``// recursively call for the` `        ``// next index` `        ``if` `(wordScore > 0)` `            ``currScore = helper(words, start + 1,` `                               ``nextCounts,` `                               ``score, memo)` `                        ``+ wordScore;` ` `  `        ``// Find the cost by not including` `        ``// the current word` `        ``currScore = Math.Max(` `            ``currScore, helper(words, start + 1,` `                              ``letterCounts, score,` `                              ``memo));` ` `  `        ``// Memoize the result` `        ``memo[key] = currScore;` ` `  `        ``// Return the maximum score` `        ``return` `currScore;` `    ``}` ` `  `    ``// Function to get the unique key` `    ``// from the  letterCounts array` `    ``// with their index` `    ``static` `string` `getKey(``int``[] letterCounts, ``int` `idx)` `    ``{` `        ``// Append the frequency of` `        ``// each character` `        ``string` `sb = ``""``;` ` `  `        ``for` `(``int` `i = 0; i < 26; ++i)` `            ``sb = sb + letterCounts[i];` ` `  `        ``// Append the index` `        ``sb = sb + ``", "``;` `        ``sb = sb + idx;` ` `  `        ``// Return the string` `        ``return` `sb;` `    ``}` `    `  `  ``static` `void` `Main() {` `    ``string``[] words = { ``"dog"``, ``"cat"``, ``"dad"``, ``"good"` `};` `    ``char``[] letters = { ``'a'``, ``'a'``, ``'c'``, ``'d'``, ``'d'``, ``'d'``, ``'g'``, ``'o'``, ``'o'` `};` `    ``int``[] 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 };`   `    ``Console.Write(maxScoreWords(words, letters, score));` `  ``}` `}`   `// This code is contributed by mukesh07.`

## Javascript

 ``

Output:

`23`

Time Complexity: O(N*X), where X is the size of the largest string in words[] array.
Auxiliary Space: O(N)

Previous
Next