https://coderun.yandex.ru/problem/traffic-lanes/description | Средняя |
---|
При организации движения по сложным перекресткам, для того, чтобы траектории водителей, выполняющих различные маневры не пересекались, вводят ограничения на возможные маневры водителей, в зависимости от того, по какой полосе движения водитель подъехал к перекрестку. Для этого используется знак «движение по полосам».
Рассмотрим дорогу, подходящую к перекрестку, на котором сходится m
дорог. Водитель, подъезжающий к перекрестку по этой дороге, потенциально может продолжить свое движение в m
различных направлениях — обратно по дороге, по которой он приехал, а также по одной из оставшихся m − 1
дорог. Пронумеруем возможные направления числами от 1 до m
слева направо с точки зрения подъезжающего водителя, номер 1 получит разворот и возврат по дороге, по которой водитель подъезжал к перекрестку, номер 2 — поворот на самую левую из дорог, и т. д.
Пусть дорога содержит n
полос для движения. Пронумеруем полосы от 1 до n
слева направо, самая левая полоса получит номер 1, следующая номер 2, и т. д. Знак «движение по полосам» разрешает каждой из полос движение по некоторым из m
возможных направлений. При этом должны выполняться следующие условия:
• если с i-й полосы разрешено движение в a-м направлении, а с j-й полосы — в b-м направлении, причем i < j, то a ≤ b;
• с каждой полосы разрешено движение хотя бы в одном направлении;
• в каждом направлении разрешено движение хотя бы с одной полосы.
Инспекция по безопасности дорожного движения заинтересовалась, а сколько различных знаков «движение по полосам» можно установить перед таким перекрестком. Помогите им найти ответ на этот вопрос.
Ввод:
4 2Вывод:
7
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
// Функция для подсчета количества возможных знаков "движение по полосам"
fun traffic(m: Int, n: Int): String {
val dp = Array(m) { LongArray(n) { 1L } } // Двумерный массив для хранения количества возможных вариантов
for (i in 1 until m) {
for (j in 1 until n) {
// Заполняем массив по формуле динамического программирования
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + dp[i - 1][j - 1]
}
}
return dp[m - 1][n - 1].toString() // Возвращаем итоговое количество вариантов
}
fun main() {
val reader = BufferedReader(InputStreamReader(System.`in`)) // Читаем вводные данные
val writer = BufferedWriter(OutputStreamWriter(System.out)) // Готовим буферизированный вывод
val (m, n) = reader.readLine().split(" ").map { it.toInt() } // Читаем значения m и n
writer.write(traffic(m, n)) // Вычисляем и записываем результат
writer.newLine()
writer.flush()
writer.close()
}