← Home
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n int
	if _, err := fmt.Fscan(reader, &n); err != nil {
		return
	}
	var s string
	fmt.Fscan(reader, &s)
	b := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &b[i])
	}

	S := 0
	T := 26 + n/2 + 1
	numNodes := T + 1

	type Edge struct {
		to, rev         int
		cap, flow, cost int
	}

	graph := make([][]Edge, numNodes)

	AddEdge := func(u, v, cap, cost int) {
		graph[u] = append(graph[u], Edge{v, len(graph[v]), cap, 0, cost})
		graph[v] = append(graph[v], Edge{u, len(graph[u]) - 1, 0, 0, -cost})
	}

	cnt := make([]int, 26)
	for i := 0; i < n; i++ {
		cnt[s[i]-'a']++
	}

	for c := 0; c < 26; c++ {
		if cnt[c] > 0 {
			AddEdge(S, c+1, cnt[c], 0)
		}
	}

	for p := 1; p <= n/2; p++ {
		i := p - 1
		j := n - p
		charI := int(s[i] - 'a')
		charJ := int(s[j] - 'a')
		bI := b[i]
		bJ := b[j]

		pairNode := 26 + p
		AddEdge(pairNode, T, 2, 0)

		for c := 0; c < 26; c++ {
			profit := 0
			if charI != charJ {
				if c == charI {
					profit = bI
				} else if c == charJ {
					profit = bJ
				}
			} else {
				if c == charI {
					if bI > bJ {
						profit = bI
					} else {
						profit = bJ
					}
				}
			}
			AddEdge(c+1, pairNode, 1, -profit)
		}
	}

	const INF int = 1e9

	flow := 0
	minCost := 0

	for flow < n {
		dist := make([]int, numNodes)
		for i := range dist {
			dist[i] = INF
		}
		parentEdge := make([]int, numNodes)
		parentNode := make([]int, numNodes)
		inQueue := make([]bool, numNodes)

		dist[S] = 0
		queue := []int{S}
		inQueue[S] = true

		for len(queue) > 0 {
			u := queue[0]
			queue = queue[1:]
			inQueue[u] = false

			for i, e := range graph[u] {
				if e.cap-e.flow > 0 && dist[e.to] > dist[u]+e.cost {
					dist[e.to] = dist[u] + e.cost
					parentNode[e.to] = u
					parentEdge[e.to] = i
					if !inQueue[e.to] {
						queue = append(queue, e.to)
						inQueue[e.to] = true
					}
				}
			}
		}

		if dist[T] == INF {
			break
		}

		push := INF
		curr := T
		for curr != S {
			p := parentNode[curr]
			idx := parentEdge[curr]
			rem := graph[p][idx].cap - graph[p][idx].flow
			if rem < push {
				push = rem
			}
			curr = p
		}

		flow += push
		minCost += push * dist[T]

		curr = T
		for curr != S {
			p := parentNode[curr]
			idx := parentEdge[curr]
			revIdx := graph[p][idx].rev
			graph[p][idx].flow += push
			graph[curr][revIdx].flow -= push
			curr = p
		}
	}

	fmt.Println(-minCost)
}