/* g++ -O2 --std=c++17 -D LOCAL A.cpp */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long LL; typedef unsigned long long ULL; #ifdef LOCAL #define dlog(x) { cerr << '[' << __LINE__ << "] " << x << endl; } #define dvar(v) { cerr << '[' << __LINE__ << "] " << #v << " = " << v << endl; } #define dvec(c) { cerr << '[' << __LINE__ << "] " << #c << " = "; for (int i = 0; i < c.size(); ++i) if (i == 0) cerr << '['<" << it.second << ' '; cerr << endl; } #define dset(s) { cerr << '[' << __LINE__ << "] " << #s << " = "; for (auto item: s) cerr << item << ' '; cerr << endl; } #else #define dlog(x) #define dvar(v) #define dvec(c) #define dmap(m) #define dset(s) #endif #define rep(i,n) for (int i = 0; i < int(n); ++i) #define repr(i,from,to) for (int i = int(from); i <= int(to); ++i) #define rrep(i,n) for (int i = (n)-1; 0 <= i; --i) #define rrepr(i,from,to) for (int i = int(from); int(to) <= i; --i) #define endl '\n' templatebool chmax(T &a, const T &b) { if (abool chmin(T &a, const T &b) { if (b P; typedef pair LP; #ifndef F #define F first #define S second #endif #ifndef umap #define umap unordered_map #endif #ifndef uset #define uset unordered_set #endif template ostream& operator<<(ostream& os, const pair& p) { return os << p.F << ':' << p.S; } /* == AC Library Cheat sheet documentation: file:///Users/nobu/Downloads/ac-library/document_ja/index.html mint mint m.pow(int p) //! return m^p mint m.inv() //! returns i that gives (m * i).val() == 1 int m.val() fenwick_tree (BIT) fenwick_tree fw(int n) //! init a[0] .. a[n-1] with all 0 void fw.add(int idx, T x); //! a[idx] += x T fw.sum(int l, int r); //! return a[l] + .. + a[r-1] dsu (UnionFind) dsu d(int n) //! prepare dsu with n nodes void d.merge(int x, int y) //! connect node x and y bool d.same(int x, int y) //! return true if node x and y are connected int d.leader(int x) //! return the leader node of the connected group int d.size(int x) //! return the size of the group that node x belongs to vector> d.groups() //! return a vector of vectors that contain the nodes in each group scc_graph scc_graph g(int n) //! create a directed graph with n nodes g.add_edge(int from, int to) //! create a directed edge from node from to node to vector> g.scc() //! return the vector of strongly connected components that are topologically sorted segtree segtree S: type of the monoid op: function to return the product of two elements e: function to return the identity element such that op(x, e) == x fo any x lazy_segtree lazy_segtree F: type of parameters to define the operation applied to the target elements mapping: function to return the element after applying the operation to the target element composition: function to combine the two sets of operation parameters to one id: function to return the operation parameter i such that mapping(i, x) = x for any x using S = int; S op(S a, S b) { return min(a, b); } S e() { return INF; } using F = int; S mapping(F f, S x) { return min(f, x); } F composition(F f, F g) { return min(f, g); } F id() { return INF; } */ // int dx[] = { 0, -1, 1, 0 }; // int dy[] = { -1, 0, 0, 1 }; // int dx[] = { -1, 0, 1, -1, 1, -1, 0, 1 }; // int dy[] = { -1, -1, -1, 0, 0, 1, 1, 1 }; const int INF = 2e9+1e4; const LL INFL = 4e18+1e9; const int MOD = 998244353; // #define USE_ACL #ifdef USE_ACL #include using namespace atcoder; using mint = static_modint; struct combination { vector fact, ifact; combination(int n):fact(n+1),ifact(n+1) { assert(n < MOD); fact[0] = 1; for (int i = 1; i <= n; ++i) fact[i] = fact[i-1]*i; ifact[n] = fact[n].inv(); for (int i = n; i >= 1; --i) ifact[i-1] = ifact[i]*i; } mint operator()(int n, int k) { if (k < 0 || k > n) return 0; if ((int)fact.size() <= n) return smallk(n, k); return fact[n]*ifact[k]*ifact[n-k]; } mint smallk(int n, int k) { if (n-k < k) k = n-k; assert(k < (int)fact.size()); mint ret = 1; for (int i = n-k+1; i <= n; ++i) ret *= i; return ret*ifact[k]; } }; ostream& operator<<(ostream& os, const mint& i) { return os << i.val(); } #endif int main() { cin.tie(0); ios::sync_with_stdio(0); cout << setprecision(20); int n; string s; cin >> n >> s; vector a(2*n); rep(i, 2*n) cin >> a[i]; vector dp(n+1, INFL); dp[0] = 0; rep(i, 2*n) { vector next(n+1, INFL); if (s[i] == '(') { rep(j, n) chmin(next[j+1], dp[j]); repr(j, 1, n) chmin(next[j-1], dp[j]+a[i]); } else if (s[i] == ')') { rep(j, n) chmin(next[j+1], dp[j]+a[i]); repr(j, 1, n) chmin(next[j-1], dp[j]); } dp.swap(next); } cout << dp[0] << endl; cout << flush; return 0; }