Sicily 1099. Packing Passengers

已知乘客總數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;

}                                 


 

發佈了135 篇原創文章 · 獲贊 6 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章