Base/Knowledges/IT/Алгоритмы/Динамическое программирование (Dynamic programming).md
2026-02-23 19:52:05 +03:00

3.1 KiB
Raw Blame History

#алгоритмы

Метод динамического программирования начинает с малых задач, а затем переходит к большой задаче. Вы решаете подзадачи, которые помогут в решении большой задачи.

  • Динамическое программирование применяется для оптимизации какой-либо характеристики при заданных ограничениях. В задаче о рюкзаке требуется максимизировать стоимость отобранных предметов с ограничениями по емкости рюкзака.
  • Динамическое программирование работает только в том случае, если каждая подзадача автономна, то есть не зависит от других подзадач.

Общий вид решения

  • в каждом решении из области динамического программирования строится таблица
  • значения ячеек таблицы обычно соответствуют оптимизируемой характеристике
  • каждая ячейка представляет подзадачу,

Самая длинная общая подстрока

const createMatrix = (row, col) => {
  const arr = Array(row).fill(Array(col).fill(0));
  return JSON.parse(JSON.stringify(arr));
}

const maxCommonSubstring = (str1, str2) => {
  const matrix = createMatrix(str1.length, str2.length);

  let maxSize = 0;
  let endIndex = 0;

  for (let i = 0; i < str1.length; i++) {
    for (let j = 0; j < str2.length; j++) {
      if (str1[i] !== str2[j]) {
        continue
      }

      matrix[i][j] = (i && j) > 0 ? matrix[i - 1][j - 1] + 1 : 1;

      if (matrix[i][j] >= maxSize) {
        maxSize = matrix[i][j];
        endIndex = j + 1;
      }
    }
  }

  return str1.slice(endIndex - maxSize, endIndex);
}


maxCommonSubstring('fish', 'hish');  // 'ish'
maxCommonSubstring('fish', 'fista'); // 'fis'
maxCommonSubstring('fish', 'fista'); // 'is'

Самая длинная общая подпоследовательность

const createMatrix = (row, col) => {
  const arr = Array(row).fill(Array(col).fill(0));
  return JSON.parse(JSON.stringify(arr));
}

const maxCommonSubsequence = (str1, str2) => {
  const matrix = createMatrix(str1.length, str2.length);

  for (let i = 0; i < str1.length; i++) {
    for (let j = 0; j < str2.length; j++) {
      if (str1[i] === str2[j]) {
        matrix[i][j] = (i && j) > 0 ? matrix[i - 1][j - 1] + 1 : 1;
      } else {
        const left = i > 0 ? matrix[i - 1][j] : 0;
        const up =  j > 0 ? matrix[i][j - 1] : 0

        matrix[i][j] = Math.max(left, up);
      }
    }
  }


  return matrix[str1.length - 1][str2.length - 1]
}

maxCommonSubsequence('fort', 'fosh'); // 2
maxCommonSubsequence('fish', 'fosh'); // 3

Источники: