Задано клетчатое
поле размером m × n. В левом нижнем углу находится
черепашка, которая может двигаться только вправо или вверх. Перед тем как достичь
правого верхнего угла, черепашка задалась
вопросом: сколько существует различных способов добраться из исходной точки до
правого верхнего угла?
Черепашка хоть и
умная, но самостоятельно посчитать столь большое количество вариантов пока не может.
Помогите черепашке найти ответ на свой вопрос.
Вход. Два натуральных числа m
и n, не превышающие 30.
Выход. Выведите
количество способов, которыми черепашка сможет добраться из левого нижнего угла
в правый верхний.
Пример
входа |
Пример
выхода |
4 3 |
10 |
динамическое
программирование
Рассмотрим
двумерный массив dp, где dp[i][j] представляет количество способов,
которыми черепашка может добраться из клетки (1, 1) до клетки (i, j).
Установим dp[1][1] = 1.
Черепашка может
попасть в ячейку (i, j) либо из ячейки (i – 1, j), либо из ячейки
(i, j – 1). Таким образом, справедливо равенство:
dp[i][j]
= dp[i – 1][j] + dp[i][j – 1]
Изначально
обнулим массив dp. Особое внимание уделяем обнулению нулевой строки и нулевого столбца
массива dp.
·
Если i = 1, то
dp[i – 1][j] = dp[0][j] = 0 и тогда
уравнение динамики упрощается до dp[1][j] = dp[1][j – 1]. Так пересчитывается первая
строка.
·
Если j = 1, то формула
принимает вид dp[i][1] = dp[i – 1][1]. Так
пересчитывается первый столбец.
Учитывая, что
dp[1][1] = 1, можно заключить, что все ячейки в первой строке и первом столбце будут
содержать значение 1, что соответствует единственному способу добраться до
каждой из этих ячеек.
Пример
Заполним массив
dp для поля размером 4 * 3:
Объявим рабочий массив dp.
#define MAX 31
long long
dp[MAX][MAX];
Читаем входные данные.
scanf("%d %d",&m,&n);
Инициализируем массив dp нулями. Во
все ячейки первой строки и первого столбца заносим 1.
memset(dp,0,sizeof(dp));
for(i = 1; i <= m; i++) dp[i][1] = 1;
for(j = 1; j <= n; j++) dp[1][j] = 1;
Пересчитываем значения ячеек массива
dp, начиная со второй строки и второго столбца.
for(i = 2; i <= m; i++)
for(j = 2; j <= n; j++)
dp[i][j] = dp[i-1][j] + dp[i][j-1];
Выводим ответ.
printf("%lld\n",dp[m][n]);
import java.util.*;
public class Main
{
public static void
main(String[] args)
{
Scanner con = new
Scanner(System.in);
int m = con.nextInt();
int n = con.nextInt();
long dp[][]
= new long [m+1][n+1];
for(int i = 1;
i <= m; i++) dp[i][1]
= 1;
for(int j = 1;
j <= n; j++) dp[1][j] =
1;
for(int i = 2;
i <= m; i++)
for(int j = 2;
j <= n; j++)
dp[i][j] = dp[i-1][j] + dp[i][j-1];
System.out.println(dp[m][n]);
con.close();
}
}
Читаем входные данные.
m, n = map(int,input().split())
Объявим список
dp.
dp = [[0] * (n + 1) for i in range(m + 1)]
Во все ячейки первой строки и первого столбца заносим 1.
for i in range(1, m + 1):
dp[i][1] = 1
for j in range(1, n + 1): dp[1][j] = 1
Пересчитываем значения ячеек массива dp, начиная со второй
строки и второго столбца.
for i in range(2, m + 1):
for j in range(2, n + 1):
dp[i][j]
= dp[i - 1][j] + dp[i][j - 1]
Выводим ответ.
print(dp[m][n])