← Все вопросы

Линейные диофантовы уравнения ax + by = c: когда есть решение и как найти все?

Задан 30 месяцев назад1.1к просмотров2 ответа
8

Нужно решить уравнение ax + by = c в целых числах (например, найти, можно ли набрать сумму c монетами номиналов через комбинацию). Когда решение существует и как получить общий вид всех решений? И как найти, например, неотрицательное или минимальное по x?

2 ответа

13
✓ Принятый ответ — помог автору

Уравнение ax + by = c имеет целочисленные решения тогда и только тогда, когда c делится на g = gcd(a, b). Это критерий из расширенного Евклида.

Алгоритм:

  1. Найди g = gcd(a,b) и коэффициенты x0, y0: a·x0 + b·y0 = g (расширенный Евклид).
  2. Если c % g != 0 → решений нет.
  3. Иначе домножь на c/g: одно частное решение x = x0·(c/g), y = y0·(c/g).

Общее решение (все целые решения):

x = x0·(c/g) + k·(b/g)
y = y0·(c/g) − k·(a/g)

для любого целого k.

bool solve_dio(long long a, long long b, long long c,
               long long &x, long long &y, long long &g) {
    long long x0, y0;
    g = ext_gcd(abs(a), abs(b), x0, y0);
    if (c % g != 0) return false;
    x = x0 * (c / g);
    y = y0 * (c / g);
    if (a < 0) x = -x;
    if (b < 0) y = -y;
    return true;
}

Сложность — O(log min(a,b)). Чтобы найти, например, минимальное неотрицательное x, сдвигай k: шаг по x равен b/g, поэтому x = ((x % (b/g)) + (b/g)) % (b/g) даёт наименьший неотрицательный x, а соответствующий y пересчитывается. Будь аккуратен со знаками a, b.

4

Частая прикладная постановка — «сколько неотрицательных решений» (задача о монетах/числе Фробениуса). После нахождения общего вида ты ограничиваешь k двумя неравенствами x ≥ 0 и y ≥ 0, получаешь диапазон допустимых k и считаешь длину этого целочисленного отрезка. Главное — не перепутать направление неравенства при отрицательных a/g или b/g. Проверь руками на маленьком примере.

Ваш ответ

Войдите, чтобы ответить на вопрос.