// Arup Guha
// 12/27/2019
// Solution to 2019 December USACO Gold Problem: Moortal Cowmbat

import java.util.*;
import java.io.*;

public class cowmbat {
	
	public static int[][] cumfreq;
	
	public static void main(String[] args) throws Exception {
		
		// Read in basic input.
		BufferedReader stdin = new BufferedReader(new FileReader("cowmbat.in"));
		StringTokenizer tok = new StringTokenizer(stdin.readLine());
		int n = Integer.parseInt(tok.nextToken());
		int numL = Integer.parseInt(tok.nextToken());
		int minStreak = Integer.parseInt(tok.nextToken());
		
		// Our string.
		char[] str = stdin.readLine().toCharArray();
		
		// Cumulative frequency array of each letter frequency.
		cumfreq = new int[n+1][numL];
		for (int i=1; i<=n; i++) {
		
			// Default.
			for (int j=0; j<numL; j++) 
				cumfreq[i][j] = cumfreq[i-1][j];
				
			// Just update this letter.
			cumfreq[i][str[i-1]-'a']++;
		}
		
		// Will store results from our DP here.
		int[][] dp = new int[n][numL];
		for (int i=0; i<n; i++) Arrays.fill(dp[i], -1);
		int[] res = new int[n];
		Arrays.fill(res, -1);
		
		// Cost function.
		int[][] cost = new int[numL][numL];
		for (int i=0; i<numL; i++) {
			tok = new StringTokenizer(stdin.readLine());
			for (int j=0; j<numL; j++)
				cost[i][j] = Integer.parseInt(tok.nextToken());
		}
		
		// This is dumb. I have to run a floyd's on this.
		for (int k=0; k<numL; k++)
			for (int i=0; i<numL; i++)
				for (int j=0; j<numL; j++)
					cost[i][j] = Math.min(cost[i][j], cost[i][k]+cost[k][j]);
		
		// Init DP table - note that for less than 2*minStreak letters, we MUST have only one letter!
		for (int idx=minStreak-1; idx<2*minStreak-1 && idx<n; idx++) {
			
			for (int j=0; j<numL; j++) {
			
				// This is the cost of changing all of the first idx+1 letters to letter j.
				dp[idx][j] = 0;
				for (int i=0; i<numL; i++)
					dp[idx][j] += cost[i][j]*count(0, idx, i);
			}
			
			// Update the best to this spot over all letters.
			res[idx] = dp[idx][0];
			for (int j=1; j<numL; j++) res[idx] = Math.min(res[idx], dp[idx][j]);
		}
		
		// Regular DP where we can build off of previous streaks.
		for (int idx=2*minStreak-1; idx<n; idx++) {
			
			// This is the cost of extending a current streak.
			for (int j=0; j<numL; j++) {
				dp[idx][j] = dp[idx-1][j];
				if (str[idx]-'a' != j) dp[idx][j] += cost[str[idx]-'a'][j];
			}
			
			// Here we try adding a new streak of letter j of length minStreak.
			for (int j=0; j<numL; j++) {
				
				// Cost of turning the last minStreak letters to j.
				int add = 0;
				for (int i=0; i<numL; i++)
					add += cost[i][j]*count(idx-minStreak+1,idx,i);
				
				// See if this helps.
				dp[idx][j] = Math.min(dp[idx][j], res[idx-minStreak] + add);
			}
			
			// Update the best we have seen.
			res[idx] = dp[idx][0];
			for (int j=1; j<numL; j++) res[idx] = Math.min(res[idx], dp[idx][j]);
		}
		
		// Output to file.
		PrintWriter out = new PrintWriter(new FileWriter("cowmbat.out"));
		out.println(res[n-1]);
		out.close();		
		stdin.close();
	}
	
	public static int count(int s, int e, int let) {
		return cumfreq[e+1][let] - cumfreq[s][let];
	}
}