#include <bits/stdc++.h>
using namespace std;
bool DBG = false;
template <typename T, typename S>
std::ostream& operator<<(std::ostream& os, const std::pair<T, S>& p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vector) {
  for (size_t i = 0; i < vector.size(); ++i) {
    os << (i > 0 ? " " : "") << vector[i];
  }
  return os;
}
template <typename T>
std::ostream& operator<<(std::ostream& os,
                         const std::vector<std::vector<T>>& vector) {
  for (size_t i = 0; i < vector.size(); ++i) {
    os << vector[i] << std::endl;
  }
  return os;
}
long long solve(int n, const string& s, const vector<int>& a) {
  const string kWord = "hard";
  const int kMaxLen = kWord.length();
  vector<vector<long long>> dp(n, vector<long long>(kMaxLen, 0));
  dp[0][0] = s[0] == 'h' ? a[0] : 0;
  for (int i = 1; i < n; ++i) {
    for (int len = 0; len < kMaxLen; ++len) {
      if (s[i] != kWord[len]) {
        dp[i][len] = dp[i - 1][len];
      } else {
        if (len > 0) {
          dp[i][len] = min(dp[i - 1][len - 1], dp[i - 1][len] + a[i]);
        } else {
          dp[i][len] = dp[i - 1][len] + a[i];
        }
      }
    }
  }
  return *min_element(dp[n - 1].begin(), dp[n - 1].end());
}
long long solve_naive(int n, const string& s, const vector<int>& a) {
  const string kWord = "hard";
  long long result = numeric_limits<long long>::max();
  for (int mask = 0; mask < (int)((1 << n)); ++mask) {
    size_t word_index = 0;
    long long mask_result = 0;
    for (int i = 0; i < n && word_index < kWord.size(); ++i) {
      if ((mask >> i) & 1) {
        word_index += (s[i] == kWord[word_index] ? 1 : 0);
      } else {
        mask_result += a[i];
      }
    }
    if (word_index < kWord.size()) {
      result = min(result, mask_result);
    }
  }
  return result;
}
string generate_string(size_t length) {
  const string kTemplate = "hard";
  stringstream stream;
  for (int i = 0; i < (int)(length); ++i) {
    stream << kTemplate[rand() % kTemplate.size()];
  }
  return stream.str();
}
vector<int> generate_weights(size_t length, size_t max_weight) {
  vector<int> w(length);
  for (int i = 0; i < (int)(length); ++i) {
    w[i] = 1 + rand() % max_weight;
  }
  return w;
}
void test() {
  srand(123);
  const size_t kTests = 1000000;
  const size_t kMaxLength = 10;
  const size_t kMaxWeight = 100;
  for (int ti = 0; ti < (int)(kTests); ++ti) {
    auto length = 1 + rand() % kMaxLength;
    auto str = generate_string(length);
    auto weights = generate_weights(length, kMaxWeight);
    auto result = solve(length, str, weights);
    auto expected_result = solve_naive(length, str, weights);
    clog << "#" << ti + 1 << " length: " << length << " str: " << str
         << " weights: " << weights << " result: " << result
         << " expected_result: " << expected_result << endl;
    assert(result == expected_result);
  }
  exit(1);
}
int main() {
  ios_base::sync_with_stdio(false);
  int n;
  string s;
  cin >> n >> s;
  vector<int> a(n);
  for (int i = 0; i < (int)(n); ++i) {
    cin >> a[i];
  }
  cout << solve(n, s, a) << endl;
  return 0;
}
