UVA10090->扩展欧几里得

本文介绍了解决UVA10090问题的方法,该问题要求求解两种不同容量盒子装载特定数量珠子的最优方案。通过应用扩展欧几里得算法,文章详细解释了如何寻找最小成本的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UVA10090 扩展欧几里得

题意:
现在有两种盒子要装n个珠子,给出每种盒子的容量和价值,求每个盒子恰好能装满的需要花费。

题解:

要求最少花费,就要考虑每种盒子装单个珠子的花费,并且求最优解时让花费较高的那种盒子尽可能少,即先求出这种盒子的最小正整数解。

题目可以等价成一个线性方程求解的问题:
n1*num1 + n2*num2 = n

解法使用扩展欧几里得定理。
只有方程有两个正整数解的时候才有答案。
需要注意的是,即使其中一个未知变量求出来了最小正整数解,另一个有可能为负数。


代码:
#include <stdio.h>
#include <iostream>
#include <cmath>
using namespace std ;
long long extend_gcd(long long a ,long long b ,long long &x ,long long &y)
{
    if(a == 0 && b == 0) return -1 ;
    if(b == 0)
    {
        x = 1 ;
        y = 0 ;
        return a ;
    }
    long long d = extend_gcd(b , a % b , y , x) ;
    y -= a / b * x ;
    return d ;
}
int main()
{
    long long n , c1 , c2 , n1 , n2 ;
    while(cin >> n , n)
    {
        cin >> c1 >> n1 >> c2 >> n2 ;
        long long x0 , y0 ;
        long long gcd = extend_gcd(n1 , n2 , x0 , y0) ;
        if(n % gcd != 0) printf("failed\n");
        else
        {
            long long num1 , num2 ;
            if(c1 * n2 > c2 * n1)
            {
                num1 = x0 * n / gcd ;
                long long r = n2 / gcd ;
                num1 = num1 % r ;
                if(num1 < 0) num1 += (r>0)?r:-r ;
                num2 = (n - num1 * n1) / n2 ;
                if(num2<0) {puts("failed");continue;}
            }
            else
            {
                num2 = y0 * n / gcd ;
                long long r = n1 / gcd ;
                num2 = num2 % r ;
                if(num2 < 0) num2 += (r>0)?r:-r ;
                num1 = (n - num2 * n2) / n1 ;
                if(num1<0) {puts("failed");continue;}
            }
            printf("%lld %lld\n", num1 , num2);
        }
    }
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值