input: from typing import List
  from random import randint
  from collections import defaultdict
  from math import inf
  def min_cost_to_form_str(target: str, fragments: List[str], expenses: List[int]) -> int:
      """
      You are given a string target, an array of strings fragments, and an integer array expenses, both arrays of the same length.
  
      Consider an initially empty string s.
  
      You can perform the following operation any number of times (including zero):
  
      Choose an index i in the range [0, fragments.length - 1].
      Append fragments[i] to s.
      The cost of operation is expenses[i].
      Return the least cost to create s equal to target. If it's not possible, return -1.
  
      Examples:
      >>> target = "abcdef", fragments = ["abdef","abc","d","def","ef"], expenses = [100,1,1,10,5]
      7
      >>> target = "aaaa", fragments = ["z","zz","zzz"], expenses = [1,10,100]
      -1
  
      Constraints:
      1 <= target.length <= 5 * 10^4
      1 <= fragments.length == expenses.length <= 5 * 10^4
      1 <= fragments[i].length <= target.length
      The total sum of fragments[i].length is less than or equal to 5 * 10^4.
      target and fragments[i] consist only of lowercase English letters.
      1 <= expenses[i] <= 10^4
      """
output:     
      dp = [inf] * (len(target) + 1)
      dp[0] = 0
  
      starts = defaultdict(list)
      for i, fragment in enumerate(fragments):
          starts[fragment[0]].append((fragment, expenses[i]))
  
      for i in range(len(target)):
          if dp[i] == inf:
              continue
  
          current_char = target[i]
          if current_char in starts:
              for frag, cost in starts[current_char]:
                  if target.startswith(frag, i):
                      dp[i + len(frag)] = min(dp[i + len(frag)], dp[i] + cost)
  
      return dp[len(target)] if dp[len(target)] != inf else -1
  