已知乘客总数n,A类飞机的运输费用cA、客容量pA,B类飞机的运输费用cB、客容量pB,设A类飞机有A架,B类飞机有B架,问是否存在pA*A+pB*B=n;若存在,还要满足cA*A+cB*B最小;若存在多种解,A应尽可能的大。
根据拓展欧几里的定理,先求出gcd(pA,pB)并判断其能否整除n,不能则表示无解。若能,先求出a、b,使得pA*a+pB*b=gcd(pA,pB),可知A、B的特解为A= n/gcd(pA,pB)*a,B= n/ gcd(pA,pB)*b,故A、B的通解则满足A= A+pB/ gcd(pA,pB)*t,B=B -pA/ gcd(pA,pB)*t。另外因为A,B>=0,联系方程则有-A/(pB/ gcd(pA,pB))<=t<=B/(pA/ gcd(pA,pB))。当cA*pB-cB*pA<=0,即A类飞机的盈利性大于等于B类飞机时,A值应尽可能大,故t应该取最大值;反之,则B值应该尽可能地大,故t应该取最小值。
Run Time: 0.02sec
Run Memory: 304KB
Code Length: 1040Bytes
Submit Time: 2012-02-19 23:32:55
// Problem#: 1099
// Submission#: 1212195
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <cmath>
using namespace std;
void exEuclid( long long a, long long b, long long& x, long long& y, long long& gcd ) {
if ( b == 0 ) {
x = 1;
y = 0;
gcd = a;
}
else {
exEuclid( b, a % b, y, x, gcd );
y -= a / b * x;
}
}
int main()
{
long long n, cA, pA, cB, pB;
long long A, B, gcd;
int N, t;
N = 1;
while ( scanf( "%lld", &n ) && n ) {
scanf( "%lld%lld%lld%lld", &cA, &pA, &cB, &pB );
exEuclid( pA, pB, A, B, gcd );
if ( n % gcd != 0 )
printf( "Data set %d: cannot be flown\n", N++ );
else {
A *= n / gcd;
B *= n / gcd;
if ( cA * pB - cB * pA <= 0 )
t = floor( (double)B / ( pA / gcd ) );
else
t = ceil( (double)-A / ( pB / gcd ) );
A += pB / gcd * t;
B -= pA / gcd * t;
printf("Data set %d: %lld aircraft A, %lld aircraft B\n", N++, A, B );
}
}
return 0;
}