我在努力改进我的算法,但没有进展。
我需要一个可重用的函数来计算x*3+y*5=n
约束条件:
n>=7
x,y,n始终为正整数
我需要找到x和y之间最短距离的组合
(绝对值)|x-y|
这是我编写的一个控制台应用程序草稿,它可以编译和工作,但正如您所见,在处理大量数据时效率很低。
我认为我缺乏数学知识来改进代码:

static void Main(string[] args)
{
    GetWarAfterMath(5000000);
    Console.ReadLine();
}

const int FIRST = 3;
const int SECOND = 5;

static void GetWarAfterMath(int n)
{
    int x = 0;
    int y = 0;
    int delta = 0;

    int i = 0;
    int j = 0;

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            if ((i * FIRST) + (j * SECOND) == n)
            {
                // Console.WriteLine(i + "*" + FIRST + "+" + j + "*" + SECOND + "=" + n);
                if (Math.Abs(i - j) < delta)
                {
                    x = i;
                    y = j;
                    delta = Math.Abs(x - y);
                }
                break;
            }

            else if ((j * FIRST) + (i * SECOND) == n)
            {
                // Console.WriteLine(j + "*" + FIRST + "+" + i + "*" + SECOND + "=" + n);
                if (j - i < delta)
                {
                    x = j;
                    y = i;
                    delta = Math.Abs(x - y);
                }
                break;
            }
        }
    }

    Console.WriteLine("THE WINNERS ARE:" + x + "*" + FIRST + "+" + y + "*" + SECOND + "=" + n);
}

编辑:
最后,在将@yves daoost、@user3386109和@hasson组合在一起之后。
时间复杂度急剧下降,执行时间为8000000:127毫秒!
这是最后一个算法:
static void Main(string[] args)
{
    GetMatch(34);
    Console.ReadLine();
}

const double FIRST = 3;
const double SECOND = 5;

static void GetMatch(double n)
{
    int x = 0;
    int y = 0;
    int finalX = 0;
    int finalY = int.MaxValue;
    for (int i = 0; i < n / FIRST; i++)
    {
        if (((n - FIRST * i) / SECOND) % 1 == 0)
        {
            y = Convert.ToInt32(((n - FIRST * i) / SECOND));
            x = i;
            if(Math.Abs(x-y) < Math.Abs(finalX-finalY))
            {
                finalX = x;
                finalY = y;
            }
        }
    }

    Console.WriteLine("THE WINNERS ARE:" + finalX + "*" + FIRST + "+" + finalY + "*" + SECOND + "=" + n + "    Calc: " +  (finalX * FIRST + finalY * SECOND));
}

请注意,正如@Yves daoost在他的第一个答案中所写的那样,使用欧几里得算法用inear丢番图方程来解决这个问题也是可能的,但是您需要反向使用欧几里得算法,我宁愿保持它的简单性。
如果有人感兴趣的话,这里有一个关于这个主题的很好的视频和一个解决方案:
数论:Diophantine Equation: ax+by=gcd(a,b)
非常感谢你的帮助。

最佳答案

这个问题在数论中很有名(它是一个线性丢番图方程)。
只有当ax+by = c时,它才能有一个解决方案,这当然总是正确的。
然后,如果您知道一些gcd(3,5)|n的解决方案,所有的解决方案都是3x°+5y°=nx=x°-5k格式的。
很容易找到解决方案,因为y=y°+3knn-5中的一个肯定是n-10的倍数。
剩下的就是在约束条件下最小化3|x°-5k-y°-3k|。最小值将通过最接近x°-5k>0的值y°+3k>0或使其中一个约束饱和的值来实现。
例如,For8kx°-y°n=173000是一个解决方案然后x°=57665产生y°=1此解决方案是可接受的,因为已满足约束。
我没有提供案例研究的全部细节,但主要教训是:不需要循环!

07-26 00:41
查看更多