UVA 10090 扩展欧几里得算法

本文介绍了解决UVA 1031问题的方法,该问题要求找到两个盒子能装满物品的最小价值方案。通过扩展欧几里得算法求解不定方程的特解和通解,并讨论了如何确定未知数的取值范围,最终求出最优解。

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

题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=12&problem=1031&mosmsg=Submission+received+with+ID+8778298

 

这道题的数据规模达到了惊人的2*10^9,所以得用long才能装得下而且只要有一丝的暴力思想就会TLE

仔细观察题目可以发现如果每一个盒子都要装满的话,则必须满足以下条件:

am1+bm2=n

这个式子很像那个扩展欧几里得里面的那个,于是很容易联想到

ax+by=gcd(a,b)=g

根绝这个方程的特点,可以判断,如果n%gcd(a,b)!=0的话,则无解(参见《数论概论》)

于是联立这两个方程我们可以解出m1,m2

解出来m1=nx/g      m2=ny/g

那么通解则应该是m1=nx/g+bt/g    m2=ny/g-at/g(注意这里不能直接用ax+by=g的最小解来计算m1和m2,另外t是一个整数)

由题目的意思,可以判断m1和m2不可能为负数

于是m1>=0,m2>=0

这样我们可以解出t的范围:-nx/b<=t<=ny/a  这里的t必须是整数

我们假定:

t1=ceil(-nx/b)

t2=floor(ny/b)

如果t1>t2的话则t就没有一个可行的解,于是肯定也是无解的情况,所以输出不可能的两种情况就明确了

接下来,我们再来计算最终的价格V

V=va*m1+vb*m2

带入m1和m2的表达式可以得到

V=va*(xn/g+bt/g)+vb*(yn/g-at/g)

=((b*va-a*vb)/g)*t+(va*xn+vb*yn)/g

这个很明显是关于t的一个一次函数(出了t意外的数都是常数)

于是V(t)的单调性由(b*va-a*vb)来确定

所以当b*va-a*vb>=0的时候,t就要取最小才能让V(t)最小

反之,则t要去取最大才行

这里t的范围(定义域)已经是确定了的,所以t只有可能有两个取值

就是t1或者t2

剩下的问题就很明确了,得到t之后,再把t的值带入m1 m2的式子里面就可以计算出答案了

 

我的代码:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值