Да, вам нужно идентифицировать рекурсивную структуру, как вы указали в одном из ваших комментариев.
Вы можете указать следующее: Допустим, вы находитесь в строке row
и в предыдущем выбранном вами столбце. было prevcol
, тогда вам нужно выбрать значение, которого нет в предыдущем столбце, и выполнить рекурсию по оставшимся строкам, и получить минимум всех таких значений, т.е. каждый раз, когда вы выбираете столбец, который не является предыдущим, и рекурсировать по оставшимся строкам, указание выбранного столбца prev было тем столбцом, который вы выбрали только сейчас.
Посмотрите на это рекурсивное уравнение, чтобы понять больше:
f( arr, row, prevcol ) = minimum of ( for all col not equal to prevcol ( arr[row][col] + f( arr, row + 1, col ) )
вы видите, как задать следующий строка и предыдущий столбец, выбранные в вызове f(arr, row +1, col )
?
Базовое условие: если row == arr.length
то есть строк не осталось, то результатом будет 0
.
И вы запомните значения, которые вы получить для каждой комбинации row
и prevcol
Java код будет:
private static int f( int[][] arr, int row, int prevCol ) {
if ( row == arr.length ) return 0;
int C = arr[row].length;
if ( dp[row][prevCol+1] != Integer.MAX_VALUE ) return dp[row][prevCol+1];
int res = Integer.MAX_VALUE;
for ( int j = 0; j < C; j++ ) {
if ( j != prevCol ) {
int val = arr[row][j] + f ( arr, row + 1, j );
res = Math.min ( res, val );
}
}
dp[row][prevCol+1] = res;
return res;
}
Вам необходимо создать массив dp
, например:
dp = new int[arr.length][arr[0].length+1];
for ( int[] r : dp ) Arrays.fill(r, Integer.MAX_VALUE);
, и вы вызываете функцию следующим образом: f( arr, 0, -1 )
, где 0
- это начало row
, а -1
- это prevcol
. Поскольку prevcol
начинается с -1
, вам необходимо сохранить значение в dp[row][prevcol+1]
, а также для вашего третьего примера ответом будет 6
, а не 9
.
row = 0, col = 1 : 2
row = 1, col = 0 : 2
row = 2, col = 2 : 1
row = 3, col = 0 : 1
2 + 2 + 1 + 1 = 6