Problem F
Marbles
Input: standard input
Output: standard output
I have some (say, n) marbles (small glass balls) and I am going to buy some boxes to store them. The boxes are of two types:
Type 1: each box costs c1 Taka and can hold exactly n1 marbles
Type 2: each box costs c2 Taka and can hold exactly n2 marbles
I want each of the used boxes to be filled to its capacity and also to minimize the total cost of buying them. Since I find it difficult for me to figure out how to distribute my marbles among the boxes, I seek your help. I want your program to be efficient also.
Input
The input file may contain multiple test cases. Each test case begins with a line containing the integer n (1 <= n <= 2,000,000,000). The second line contains c1 and n1, and the third line contains c2 and n2. Here, c1, c2, n1 and n2 are all positive integers having values smaller than 2,000,000,000.
A test case containing a zero for n in the first line terminates the input.
Output
For each test case in the input print a line containing the minimum cost solution (two nonnegative integers m1 and m2, where mi = number ofType i boxes required) if one exists, print "failed" otherwise.
If a solution exists, you may assume that it is unique.
Sample Input
43
1 3
2 4
40
5 9
5 12
0
Sample Output
13 1
failed
___________________________________________________________________
Rezaul Alam Chowdhury
“The easiest way to count cows in a grazing field is to count how many hooves are there and then divide it by four!”
题意很简单:ax+by=c; 求c1x+c2y的最小值。
首先要说一下两个函数的区别。
floor(1.00001) = 1; floor(1.99999) = 1;
ceil(1.00001) = 2; ceil(1.99999) =2;
其实是对函数的取整的问题。
思路:当然,首先要判断是否有解,这个过程。。 g=gcd(a,b);
由于 x = x*c/g + k*(b/g);
y = y*c/g - k*(a/g); x>=0 && y>=0 ,因为不能能买负数个东西。
==> x*c/b <=k <=c*y/a;
ok,这个就是k的取值范围。
这里就要用到一个问题,k是整数,如果取值才是合理的呢?
ceil(x*c/b)<=k<=floor(c*y/a);
这里不解释,1.24<=k<=4.25 ==> 2<=k<=4;?? enen .
现在k的范围求出来了,那么现在就是求对应的x,和y的值了。
有式子 c1x+c2y = c1*x+c2*(c-a*x)/b = c1*x - c2*a/b*x + c2*a/b;
就是化简成只有x的情况进行讨论。
我们只需要看c1*x - c2*a/b*x这一部分, x*( c1-c2*a/b )
当c1-c2*a/b<0的时候,x应该越到越好,这就可以根据已经求出的k来做了。
当c1-c2*a/b>0的时候,x应该越小越好。同理。
当c1-c2*a/b=0的时候,当然,就随意在前面一种情况里都是一样的。
code:
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 using namespace std; 7 typedef long long LL; 8 9 LL Ex_GCD(LL a,LL b,LL &x,LL& y) 10 { 11 if(b==0) 12 { 13 x=1; 14 y=0; 15 return a; 16 } 17 LL g=Ex_GCD(b,a%b,x,y); 18 LL hxl=x-(a/b)*y; 19 x=y; 20 y=hxl; 21 return g; 22 } 23 int main() 24 { 25 LL n,c1,n1,c2,n2; 26 LL c,a,b,x,y,g; 27 while(scanf("%lld",&n)>0) 28 { 29 if(n==0)break; 30 scanf("%lld%lld",&c1,&n1); 31 scanf("%lld%lld",&c2,&n2); 32 a=n1; 33 b=n2; 34 c=n; 35 g=Ex_GCD(a,b,x,y); 36 if(c%g!=0) 37 { 38 printf("failed "); 39 continue; 40 } 41 LL lowx =ceil ( -1.0*x*c/(double)b); 42 LL upx = floor( c*y*1.0/(double)a ); 43 if(upx<lowx) 44 { 45 printf("failed "); 46 continue; 47 } 48 if(c1*b<=a*c2)/** x越大越好,就取上限值 */ 49 { 50 x=x*(c/g)+upx*(b/g); 51 y=y*(c/g)-upx*(a/g); 52 } 53 else 54 { 55 x=x*(c/g)+lowx*(b/g); 56 y=y*(c/g)-lowx*(a/g); 57 } 58 printf("%lld %lld ",x,y); 59 } 60 return 0; 61 }