示例:
A = 5,B = 2,N = 12
然后让x = 2,y = 1,所以12 - (5(2)+ 2(1))= 0.
另一个例子:
A = 5,B = 4,N = 12
这里x = 1,y = 1是最好的。注意x = 2,y = 0会更好,除了不允许x = 0。
我正在寻找快速的东西。
注意找到Ax + By的值就足够了。没有必要明确地给出x或y。
答案 0 :(得分:3)
如果gcd(A,B)| N,那么N是你的最大值。否则,它是gcd(A,B)的最大倍数小于N.以4x + 2y = 13为例,该值为gcd(4,2)* 6 = 12实现由4(2)+2(2)= 12(在许多解决方案中)。
作为公式,您的最大值是Floor(N / gcd(A,B))* gcd(A,B)。
修改:如果x和y都必须为正数,则可能无效。但是,如果A + B> N,则甚至不会成为解决方案。这是一个适合你的算法...
from math import floor, ceil
def euclid_wallis(m, n):
col1 = [1, 0, m]
col2 = [0, 1, n]
while col2[-1] != 0:
f = -1 * (col1[-1] // col2[-1])
col2, col1 = [x2 * f + x1 for x1, x2 in zip(col1, col2)], col2
return col1, col2
def positive_solutions(A, B, N):
(x, y, gcf), (cx, cy, _) = euclid_wallis(A, B)
f = N // gcf
while f > 0:
fx, fy, n = f*x, f*y, f*gcf
k_min = (-fx + 0.) / cx
k_max = (-fy + 0.) / cy
if cx < 0:
k_min, k_max = k_max, k_min
if floor(k_min) + 1 <= ceil(k_max) - 1:
example_k = int(floor(k_min) + 1)
return fx + cx * example_k, fy + cy * example_k, n
if k_max <= 1:
raise Exception('No solution - A: {}, B: {}, N: {}'.format(A, B, N))
f -= 1
print positive_solutions(5, 4, 12) # (1, 1, 9)
print positive_solutions(2, 3, 6) # (1, 1, 5)
print positive_solutions(23, 37, 238) # (7, 2, 235)
答案 1 :(得分:0)
一种蛮力O(N^2 / A / B)
算法,用普通的Python3实现:
import math
def axby(A, B, N):
return [A * x + B * y
for x in range(1, 1 + math.ceil(N / A))
for y in range(1, 1 + math.ceil(N / B))
if (N - A * x - B * y) >= 0]
def bestAxBy(A, B, N):
return min(axby(A, B, N), key=lambda x: N - x)
这符合你的例子:
In [2]: bestAxBy(5, 2, 12)
Out[2]: 12 # 5 * (2) + 2 * (1)
In [3]: bestAxBy(5, 4, 12)
Out[3]: 9 # 5 * (1) + 4 * (1)
答案 2 :(得分:0)
不知道可能是什么算法,但我认为你需要类似的东西(C#)
static class Program
{
static int solve( int a, int b, int N )
{
if( a <= 0 || b <= 0 || N <= 0 )
throw new ArgumentOutOfRangeException();
if( a + b > N )
return -1; // Even x=1, y=1 still more then N
int x = 1;
int y = ( N - ( x * a ) ) / b;
int zInitial = a * x + b * y;
int zMax = zInitial;
while( true )
{
x++;
y = ( N - ( x * a ) ) / b;
if( y <= 0 )
return zMax; // With that x, no positive y possible
int z = a * x + b * y;
if( z > zMax )
zMax = z; // Nice, found better
if( z == zInitial )
return zMax; // x/y/z are periodical, returned where started, meaning no new values are expected
}
}
static void Main( string[] args )
{
int r = solve( 5, 4, 12 );
Console.WriteLine( "{0}", r );
}
}