Эту проблему можно решить, используя подход сверху вниз.
Вы начинаете с места в первом ряду и оттуда идете вниз. У вас есть два варианта:
a) Продолжить в том же столбце - но вы должны принять во внимание, что у вас достаточно строк для переключателей K
. Таким образом, ваше условие должно быть remaining_rows >= K
, тогда вы можете использовать эту опцию, иначе нет.
b) Переключите ваш столбец на любой другой столбец. Рассмотрим все столбцы.
Из этих двух вариантов взять минимум.
Тогда рекурсивное уравнение будет иметь вид:
getMin(r, c, K) = min(
(R - (r+1) >= K ? getMin(r+1, c, K) + A[r][c] : A[r][c] ),
( for all j != c, j < C: min(getMin(r+1, c, K-1)) )
)
, где A
- матрица ввода и R
- это количество строк, C
- это количество столбцов в A
.
, и вы берете минимум от getMin(0, c, K )
для всех c = 0
до C
Вы можете запомнить решение для каждого r, c, K
.
. Для K = 0
просто пройти вниз по столбцу и получить сумму.
Код в Java:
class Main {
private static int[][][] dp;
public static void main(String[] args) {
int[][] A = { { 0, 1, 2 }, { 4, 3, 1 }, { 6, -2, 5 }, { 1, 4, -3 } };
int K = 3;
dp = new int[A.length][A[0].length][K + 1];
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < A[0].length; j++) {
for (int k = 1; k <= K; k++) {
dp[i][j][k] = Integer.MAX_VALUE;
}
}
}
int res = Integer.MAX_VALUE;
for (int j = 0; j < A[0].length; j++)
res = Math.min(res, getMin(A, 0, j, K));
System.out.println(res);
}
private static int getMin(int[][] A, int r, int c, int K) {
int R = A.length, C = A[0].length;
if (r > R - 1 || c > C - 1)
return Integer.MAX_VALUE;
if (K == 0) {
int sum = 0;
for (int i = r; i < R; i++)
sum += A[i][c];
return sum;
}
if (dp[r][c][K] != Integer.MAX_VALUE)
return dp[r][c][K];
int min = Integer.MAX_VALUE;
int rem_rows = R - (r + 1);
for (int j = 0; j < C; j++) {
if (j == c && rem_rows >= K) {
int s = getMin(A, r + 1, j, K);
if (s != Integer.MAX_VALUE) {
min = Math.min(min, s + A[r][c]);
} else {
min = Math.min(min, A[r][c]);
}
} else if (j != c) {
int m = getMin(A, r + 1, j, K - 1);
if (m != Integer.MAX_VALUE) {
min = Math.min(min, m + A[r][c]);
} else {
min = Math.min(min, A[r][c]);
}
}
}
dp[r][c][K] = min;
return min;
}
}
Вы можете играть с живым кодом здесь