D - tourists

Gym - 100883H

一共有\(N\)个人要乘船出行。
你有两条船,每次载人出去一次花费\(c_1,c_2\),载人量为\(n_1,n_2\)
船必须载满才能出行,求运送所有人的最小花费。

首先利用裴蜀定理和扩展欧几里得求出一组解。
\(n_1x + n_2y = gcd(n_1,n_2) = g\)

然后判断\(N Mod g\)是否为0,不为0无解。

然后\(x*=N/g,y*=N/g\),使得\(n_1x +n_2y=N\)

然后考虑\(x = x + kn_2, y = y - kn_1\),上面的式子仍然满足

判断\(c_1 * n_2\)\(c_2 *n_1\)的大小关系即可。


#include<bits/stdc++.h>
using namespace std;

long long N,n1,n2,c1,c2;

long long exgcd(long long a,long long b,long long &x,long long &y){
    if(!b){
        long long ret = a; x = 1; y = 0; return ret;
    }
    long long ret = exgcd(b,a % b,y,x);
    y -= a/b * x;
    return ret;
}

int main(){
    while(1){
        scanf("%lld",&N);
        if(N == 0) break;
        
        scanf("%lld%lld%lld%lld",&c1,&n1,&c2,&n2);
        
        long long x = 0, y = 0;
        long long g = exgcd(n1,n2,x,y);
        if(N % g != 0) { puts("failed"); continue; }
        
        x *= N/g; y *= N/g;
        if(n1 * c2 < n2 * c1){
            x = (x % n2 + n2) % n2;
            y = (N - n1 * x) / n2; 
        }else{
            y = (y % n1 + n1) % n1;
            x = (N - n2 * y) / n1;
        }
        printf("%lld %lld\n",x,y);
    }
    return 0;
}

posted @ 2020-07-24 19:48  zhuzihan  阅读(89)  评论(0编辑  收藏  举报