You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

判断数值是否符合特定线性组合的高效算法与数学解法探究

Great question! This is a classic linear Diophantine equation problem with non-negative integer constraints, and we can solve it efficiently even for extremely large numbers by leveraging number theory. Let's break this down step by step:


Problem Restatement

We need to determine if there exist non-negative integers (k \geq 0, p \geq 0) such that:

A*k + B + C*p = N

Where (A, C) are positive integers (we'll handle edge cases where either is 0 too), (B, N) are non-negative integers, and (N \geq 0).


Step 1: Simplify the Equation

First, rearrange the original equation to isolate the linear combination of (k) and (p):

A*k + C*p = M

where (M = N - B).

Critical Initial Check

If (M < 0): There's no possible solution. The left-hand side is a sum of non-negative terms, so it can never equal a negative number. Return false immediately.


Step 2: Handle Trivial Edge Cases (A or C = 0)

  • If both (A = 0) and (C = 0): The equation reduces to (B = N). Return true only if (N = B).
  • If (A = 0): We need (C*p = M). Return true if (M \geq 0) and (M) is evenly divisible by (C) (since (p = M/C) must be non-negative).
  • If (C = 0): Similarly, return true if (M \geq 0) and (M) is evenly divisible by (A) (since (k = M/A) must be non-negative).

Step 3: Number Theory for Positive A and C

Assuming (A > 0) and (C > 0):

Step 3.1: Check Divisibility by GCD

Compute (g = \gcd(A, C)) (greatest common divisor of (A) and (C)) using the Euclidean algorithm (fast even for 100-digit numbers):

  • If (M \mod g \neq 0): No solution exists. The left-hand side (Ak + Cp) is always a multiple of (g), so (M) must also be a multiple of (g). Return false.
  • If (M \mod g == 0): Divide the entire equation by (g) to simplify:
    A'*k + C'*p = M'
    
    Where (A' = A/g), (C' = C/g), (M' = M/g). Now (A') and (C') are coprime (their GCD is 1).

Step 3.2: Check for Non-Negative Solutions

Since (A') and (C') are coprime, we use properties of the Frobenius Number (for two coprime integers):

  • The largest integer that cannot be expressed as (A'*k + C'*p) (with (k,p \geq 0)) is (F = A'*C' - A' - C').
  • If (M' \geq (A'-1)*(C'-1)) (this is (F + 1)), then a solution must exist—return true.
  • If (M' < (A'-1)*(C'-1)): We need to check a small set of values to find a valid pair. To minimize iterations, loop over the smaller of (A') or (C'):
    • For example, if (A') is smaller, iterate (k) from 0 to (M' // A'). For each (k), compute (remaining = M' - A'*k). If (remaining \geq 0) and (remaining \mod C' == 0), then (p = remaining / C') is non-negative—return true.
    • If none of the iterations find a valid pair, return false.

Example Walkthroughs

Let's verify your sample cases:

  1. n=24: Original equation (2k + 2 + 3p = 24) → (M = 24-2=22). (\gcd(2,3)=1), (M'=22). ((2-1)*(3-1)=2), and 22 ≥ 2 → solution exists.
  2. n=11: (M=11-2=9), 9 ≥ 2 → solution exists.
  3. n=15: (M=15-2=13), 13 ≥ 2 → solution exists.

Efficient Implementation for Large Numbers

This approach works seamlessly for huge values (like your example with 1e6 and 37 billion) because:

  • GCD computation runs in (O(\log(\min(A,C)))) time, which is near-instant even for massive numbers.
  • The loop (when needed) runs at most (\min(A', C')) times, which is small relative to the size of large inputs.

Sample Python Code

import math

def has_non_negative_solution(A, B, C, N):
    M = N - B
    if M < 0:
        return False
    
    # Handle cases where A or C is 0
    if A == 0 and C == 0:
        return M == 0
    if A == 0:
        return M % C == 0 and (M // C) >= 0
    if C == 0:
        return M % A == 0 and (M // A) >= 0
    
    # Now A and C are positive
    g = math.gcd(A, C)
    if M % g != 0:
        return False
    
    A_prime = A // g
    C_prime = C // g
    M_prime = M // g
    
    # Check if M' is large enough to guarantee a solution
    frobenius_threshold = (A_prime - 1) * (C_prime - 1)
    if M_prime >= frobenius_threshold:
        return True
    
    # Check small values, iterate over the smaller of A' or C' to minimize steps
    if A_prime <= C_prime:
        max_k = M_prime // A_prime
        for k in range(max_k + 1):
            remaining = M_prime - A_prime * k
            if remaining >= 0 and remaining % C_prime == 0:
                return True
    else:
        max_p = M_prime // C_prime
        for p in range(max_p + 1):
            remaining = M_prime - C_prime * p
            if remaining >= 0 and remaining % A_prime == 0:
                return True
    
    # No solution found
    return False

# Test your samples
print(has_non_negative_solution(2, 2, 3, 24))  # True
print(has_non_negative_solution(2, 2, 3, 11))  # True
print(has_non_negative_solution(2, 2, 3, 15))  # True

# Test your large number example
A = 1000000
B = 37383993
C = 37326328393
N = 747437446239902
print(has_non_negative_solution(A, B, C, N))  # Computes efficiently

内容的提问来源于stack exchange,提问作者Mohammad Hossein Amri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:49:35