UVA10090->扩展欧几里得
2016-07-28 11:37
267 查看
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 ; }
相关文章推荐
- linux 的动静态库
- netty 第一章 ServerBootstrap 和 ClientBootstrap
- Spark 2.0技术预览
- java配置数据库连接池的方法步骤
- 开源GIS_Tomcat解压版配置
- eclipse安装jetty插件
- MySQL备份之分库分表备份脚本
- nodejs 脚本获取webservice数据可key值索引
- mysql深入之视图和索引
- vim IDE打造
- android 版本更新之JAR的应用
- spring任务
- CoordinatorLayout + AppBarLayout + SwipeRefreshLayout在eclipse上使用的方法和问题记录
- Java编程:java.lang.Void类分析
- linux/centos/redhat 安装mono环境 X64系统
- Android:MD5工具类及单例Toast(小白进)
- luigi学习6--parameters详解
- S2 易买网总结
- eclipse项目下显示隐藏文件
- cocos2dx 如何将int转成CCString