Let's run the Floyd – Warshall algorithm on the matrix a_{ij} to determine the shortest time required to replace each letter with any other letter.
Then construct a cost matrix , where cst[i][j]~(1 \le i \le n) represents the minimum number of days needed to change the letter s[i - 1] into the letter .
For convenience in further calculations, we build a matrix that contains the column-wise prefix sums of the cost matrix :
Let dp[i][j] denote the minimum number of days required to transform the first letters of the string into a string that satisfies Bessie’s new requirements, with the last letters of the new string being the letter .
We can write the dynamic equations as follows:
Suppose the first i - 1 letters of уhave already been transformed into a string whose last letters are all . Then we simply change the letter s[i - 1] to , which can be done in cst[i][j] days.
To ensure that the last letters of the new string are all , consider the values dp[i - k][0], dp[i - k][1], ..., dp[i - k][m - 1]. Choose the smallest among them — that is, we transform the first i - k letters of into a string satisfying Bessie's new requirements (we don't care which letter the substring of length i - k ends with; we only care that it can be obtained in the minimum number of days). After that, we replace the last letters of the original string — namely s[i - k], s[i - k + 1], ..., , s[i - 1] — with the letter , which takes
days. This sum can be computed in constant time using the prefix sum array :
We maintain an auxiliary array , where
Thus, the dynamic programming equation for this case (i \ge k) takes the following form:
It remains to choose the smaller of the two options for dp[i][j].
The answer to the problem is the value
We don't care which particular letters the new word Bessie ends with.
Example
In this example, the optimal solution is as follows: replace with , then with , and after that replace both 's with . The total cost of the changes is 1 + 4 + 0 + 0 = 5 days, and the resulting string will be .
Using the matrix a_{ij}, we construct the cost matrix . We also compute the matrix .
All values of dp[1][j]~(0 \le j \le 4) will be equal to , since the length of the stripe cannot be less than k = 2. Accordingly, mn[1] = +∞.
Let us now consider the process of computing the values of dp[2][j] (0 ≤ j ≤ 4).
dp[2][0] = ("ab" \to "aa") = cnt[''''] + cnt[''][''] = 0 + 2 = 2;
dp[2][1] = ("ab" \to "bb") = cnt[''''] + cnt[''''] = 1 + 0 = 1;
dp[2][2] = ("ab" \to "cc") = cnt[''''] + cnt[''''] = 4 + 4 = 8;
dp[2][3] = ("ab" \to "dd") = cnt[''''] + cnt[''''] = 4 + 4 = 8;
dp[2][4] = ("ab" \to "ee") = cnt[''''] + cnt[''''] = 4 + 4 = 8;
When computing the values of dp[3][j]~(0 \le j \le 4), the equation
will not be used, since mn[1] = +∞. Therefore, to obtain strips from the first three letters, one can only extend the strips of length two that have already been constructed:
dp[3][0] = dp[2][0] + cst[''''] = 2 + 5 = 7~("aaa");
dp[3][1] = dp[2][1] + cst[''''] = 1 + 5 = 6~("bbb");
dp[3][2] = dp[2][2] + cst[''''] = 8 + 0 = 8~("ccc");
dp[3][3] = dp[2][3] + cst[''''] = 8 + 3 = 11~("ddd");
dp[3][4] = dp[2][4] + cst[''''] = 8 + 2 = 10~("eee");
The value of can be obtained in two ways:
dp[4][0] = dp[3][0] + cst[''][''] = 7 + 5 = 12~("aaaa");
or
dp[4][0] = ps[4][0] - ps[2][0] + mn[2] = 12 - 2 + 1 = 11~("bbaa");
The second case is more optimal — two letters '' are appended to a two-character string. The value mn[2] = 1 is achieved for the string "", which means the optimal string is "".
Algorithm implementation
Let us define the following arrays:
— the minimum cost of transforming letter into letter .
cst[i][j] — the cost of replacing the -th letter of the original string (indexing starts from ) with letter . Formally
— the prefix sum array of , used to quickly compute the cost of changing a substring of length :
dp[i][j] — the minimum number of days required to transform the first letters of string into a valid string (according to the stripe rules), where the last letters of the result are letter .
— the minimum over all of dp[i][j], i.e. the best solution for the first characters.
#define MAXN 100005
#define ALPH 26
int a[ALPH][ALPH], cst[MAXN][ALPH], ps[MAXN][ALPH], dp[MAXN][ALPH], mn[MAXN];Read the input data.
cin >> n >> m >> k;
cin >> s;
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
cin >> a[i][j];Run the Floyd - Warshall algorithm on the matrix . After it finishes, contains the minimum number of days required to change letter into letter .
for (x = 0; x < m; x++)
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
a[i][j] = min(a[i][j], a[i][x] + a[x][j]);We have m \le 26 letters. Let us construct a cost matrix such that cst[i][j]~(1 \le i \le n) contains the minimum number of days required to change the letter s[i - 1] into letter . The letters in the string are indexed starting from .
For convenience in further computations, we'll build a matrix , which contains the column-wise prefix sums of the cost matrix :
for (i = 1; i <= n; i++)
for (j = 0; j < m; j++)
{
cst[i][j] = a[s[i - 1] - 'a'][j];
ps[i][j] = ps[i - 1][j] + cst[i][j];
}Initialize the arrays.
memset(dp, 0x3f, sizeof dp);
memset(mn, 0x3f, sizeof mn);
mn[0] = 0;We compute the values of the array cells. The letter corresponds to the character s[i - 1]. The letters in variable are numbered from (corresponding to letter '') to m - 1. Intuitively, at each step , Bessie decides:
either to continue pressing the same button as before,
or to start a new stripe of length at least .
We choose the cheaper option and save the result in dp[i][j].
We start the loop over from because the first valid stripe can only end at position .
for (i = k; i <= n; i++)
for (j = 0; j < m; j++)
{We continue the current stripe. The letter s[i - 1] of the original string is changed to . That is:
the previous i - 1 letters have already been transformed and end with ;
now add the -th letter s[i - 1], also turning it into ;
the total cost will be dp[i - 1][j] + cst[i][j].
dp[i][j] = min(dp[i][j], dp[i - 1][j] + cst[i][j]);We start a new stripe of letters. We assume that at position a new stripe of exactly (or more) letters ends, consisting of the letter . To do this:
Take the best transformation of the first (i - k) letters (everything before the new stripe): mn[i - k].
Add the cost of replacing the last letters (from i - k + 1 to ) with :
dp[i][j] = min(dp[i][j], ps[i][j] - ps[i - k][j] + mn[i - k]);After computing all dp[i][j] for a fixed , we store the best (minimum) value among all in .
mn[i] = min(mn[i], dp[i][j]);
}Print the answer.
cout << mn[n] << "\n";