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\n");
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\n");
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\n",x,y);
59 }
60 return 0;
61 }