Educational Round #5 — Editorial
For each index , find the maximum index such that . This can be done using binary search. Next, the desired index is defined as the position where the value is attained for .
Thus, for each index , we need to find the largest possible index , and then, among all obtained pairs , determine the maximum difference .
Example
Consider the third example.
Let . The largest index satisfies the condition . The value of is attained at index .
Let's declare the constants and arrays.
#define MAX 50010 #define LOGMAX 16 int dp_max[MAX][LOGMAX], dp_min[MAX][LOGMAX]; int a[MAX];
The function Build_RMQ_Array строит таблицы для быстрых запросов минимума () и максимума ():
stores the minimum value over the segment of length starting at position .
stores the index of the element with the maximum value over the segment of length starting at .
void Build_RMQ_Array(int *b)
{
int i, j;
for (i = 1; i <= n; i++)
{
dp_min[i][0] = b[i];
dp_max[i][0] = i;
}
for (j = 1; 1 << j <= n; j++)
for (i = 1; i + (1 << j) - 1 <= n; i++)
{
if (b[dp_max[i][j - 1]] > b[dp_max[i + (1 << (j - 1))][j - 1]])
dp_max[i][j] = dp_max[i][j - 1];
else
dp_max[i][j] = dp_max[i + (1 << (j - 1))][j - 1];
dp_min[i][j] =
min(dp_min[i][j - 1], dp_min[i + (1 << (j - 1))][j - 1]);
}
}The RangeMaxQuery function returns the index of the maximum element in the subsegment .
int RangeMaxQuery(int i, int j)
{
int k = 0;
while ((1 << (k + 1)) <= j - i + 1) k++;
if (a[dp_max[i][k]] > a[dp_max[j - (1<<k) + 1][k]])
return dp_max[i][k];
else
return dp_max[j - (1<<k) + 1][k];
}The RangeMinQuery function returns the minimum value in the subsegment .
int RangeMinQuery(int i, int j)
{
int k = 0;
while ((1 << (k + 1)) <= j - i + 1) k++;
return min(dp_min[i][k],dp_min[j - (1<<k) + 1][k]);
}The BinSearch function uses binary search on the interval to find the largest index such that all elements between and are greater than .
int BinSearch(int Left, int Right)
{
int MinValue = a[Left++];
if (RangeMinQuery(Left,Right) > MinValue) return Right;
while (Right > Left)
{
int Middle = (Left + Right) / 2;
if (RangeMinQuery(Left,Middle) > MinValue)
Left = Middle + 1;
else
Right = Middle;
}
if (dp_min[Left][0] <= MinValue) Left--;
return Left;
}The main part of the program. Process the test cases sequentially.
while(scanf("%d",&n) == 1)
{
for(i = 1; i <= n; i++) scanf("%d",&a[i]);Build the and arrays.
Build_RMQ_Array(a);
For each index :
Using , find the largest index such that all elements in the interval are greater than ;
In the interval find the index where the maximum value is reached.
Check whether is the largest difference.
res = 0;
for(i = 1; i <= n; i++)
{
k = BinSearch(i, n);
j = RangeMaxQuery(i,k);
if (j - i > res) res = j - i;
}Print the result. If , we should print .
if (res == 0) res = -1;
printf("%d\n",res);
}Bessie has been playing the popular game Moortal Cowmbat for a long time. However, the game developers have recently released an update that forces her to change her usual play style.
The game uses buttons, labeled with the first lowercase letters of the Latin alphabet. Bessie’s favorite combination of moves is a string of length , describing a sequence of button presses. After the update, each combo must consist of a sequence of "stripes", where a stripe is defined as a consecutive sequence of the same button pressed at least times in a row. Bessie wants to modify her favorite combination to obtain a new string of the same length , but consisting of stripes that satisfy the updated rules.
It is known that Bessie needs days to learn to press button instead of button in any specific position of her combination (that is, replacing one occurrence of letter in with letter costs days).
Note that sometimes the replacement can be done faster through intermediate buttons. For example, changing directly to may be more expensive than performing two consecutive replacements . Thus, there may exist a transformation path from to with a smaller total cost than the direct replacement.
Help Bessie determine the minimum number of days required to create a combination that satisfies the new requirements.
Input. The first line contains three integers: , , and .
The second line contains the string .
The next lines each contain integers — the elements of the matrix , where is the number of days required to replace button with button . It is guaranteed that and for all .
Output. Print the minimum number of days Bessie needs to create a combination that meets the new requirements.
Example. In this example, the optimal solution is to replace with , then replace with , and finally replace both 's with . The total cost of these changes is days, and the resulting string will be .
5 5 2 abcde 0 1 4 4 4 2 0 4 4 4 6 5 0 3 2 5 5 5 0 4 3 7 0 5 0
5
Let's run the Floyd – Warshall algorithm on the matrix to determine the shortest time required to replace each letter with any other letter.
Then construct a cost matrix , where represents the minimum number of days needed to change the letter into the letter .
For convenience in further calculations, we build a matrix that contains the column-wise prefix sums of the cost matrix :
Let 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 letters of уhave already been transformed into a string whose last letters are all . Then we simply change the letter to , which can be done in days.
To ensure that the last letters of the new string are all , consider the values . Choose the smallest among them — that is, we transform the first letters of into a string satisfying Bessie's new requirements (we don't care which letter the substring of length 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 — 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 takes the following form:
It remains to choose the smaller of the two options for .
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 days, and the resulting string will be .
Using the matrix , we construct the cost matrix . We also compute the matrix .
All values of will be equal to , since the length of the stripe cannot be less than . Accordingly, .
Let us now consider the process of computing the values of dp[2][j] (0 ≤ j ≤ 4).
'''''']['';
'''''''';
'''''''';
'''''''';
'''''''';
When computing the values of , the equation
will not be used, since . Therefore, to obtain strips from the first three letters, one can only extend the strips of length two that have already been constructed:
'''';
'''';
'''';
'''';
'''';
The value of can be obtained in two ways:
'']['';
or
;
The second case is more optimal — two letters '' are appended to a two-character string. The value is achieved for the string "", which means the optimal string is "".
Let us define the following arrays:
— the minimum cost of transforming letter into letter .
— 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 :
— 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 , 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 letters. Let us construct a cost matrix such that contains the minimum number of days required to change the letter 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 . The letters in variable are numbered from (corresponding to letter '') to . 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 .
for (i = 1; i <= n; i++)
for (j = 0; j < m; j++)
{We continue the current stripe. The letter of the original string is changed to . That is:
the previous letters have already been transformed and end with ;
now add the -th letter , also turning it into ;
the total cost will be .
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 letters (everything before the new stripe): .
• Add the cost of replacing the last letters (from до ) with :
If fewer than characters have been processed, a stripe of this length cannot be formed. Therefore, .
if (i >= k)
dp[i][j] = min(dp[i][j], ps[i][j] - ps[i - k][j] + mn[i - k]);After computing all 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";

The player starts with and must consecutively answer questions. Before each question, the player can:
stop the game and take the money currently in hand;
answer the question. If the answer is incorrect, the player leaves the game with nothing. If the answer is correct, the amount of money doubles, and the game proceeds to the next question.
After correctly answering the last question, the player keeps the winnings. The player's goal is to maximize the expected amount of money won.
For each individual question, the player answers correctly with probability . Assume that is uniformly distributed over the interval .
Input. Each line represents a separate test case and contains two numbers: an integer and a real number . The last line contains two zeros and should not be processed.
Output. For each test case, print on a separate line the maximum expected amount of money the player can win under the optimal strategy. Print the answer with three decimal digits.
1 0.5 1 0.3 2 0.6 24 0.25 0 0
1.500 1.357 2.560 230.138
Let be the maximum possible expected winnings if the player has to answer questions and the initial amount is .
If , the player keeps the initial amount, that is, .
The probability of answering a question correctly is , where . If the player answers the first question correctly, there remain questions, and the prize doubles to . With probability , the player gives an incorrect answer and loses everything. Therefore, the expected winnings after the first question is
If this value exceeds the current amount , it is advantageous to continue the game; otherwise, the player should stop. Thus, the expected winnings after making the decision to continue is
Since the probability is uniformly distributed over the interval , then
If , then the probability of a correct answer equals one, and the player should answer all questions, obtaining a final prize of .
Example
Let us consider the third test, where . The initial amount .
Let us compute the value of using :
Let us compute the value of using :
The function integral computes the value of the integral
for given real numbers and . When , the guessing probability equals one, so the value of the integral is set to .
Below is the region whose area corresponds to the value of the integral :
Let us find the intersection point of the lines and :
Let . We consider the value of the integral as the sum of two parts: + . Depending on the position of the point relative to and , we compute the value of the integral .
If , then + =
If , then + = = .
If , then + = = .
double integral(double a, double k)
{
double s = 0, temp = a / k;
if (t == 1) return max(a,k);
if (temp > 1) return a * (1 - t);
if (temp >= t) s = a * (temp - t);
else temp = t;
s += k * (1 – temp * temp) / 2;
return s / (1 - t);
}The function f recursively computes the value of .
double f(int n, int a)
{
if (!n) return a;
double k = f(n - 1,2 * a);
return integral(a,k);
}The main part of the program. Read the input data, and print the value of .
while(scanf("%d %lf",&n,&t),n + t)
printf("%.3lf\n",f(n,1));