GYM 100883 H.tourists(一元线性同余方程)

201 篇文章 10 订阅

Description
n名游客坐船,第一种船一次可以带n1个人,花费c1,第二种船一次可以带n2个人,花费c2,求这n名游客坐船所花的最小花费对应的两种船的数量
Input
多组用例,每组用例首先输入游客数量n,之后输入第一种船的花费c1和容量n1,然后输入第二种船的花费c2和容量n2
Output
如果x艘第一种船和y艘第二种船恰可以带走n名游客输出所有满足条件中最小花费对应的x和y,如果不存在合法方案则输出failed
Sample Input
43
1 3
2 4
40
5 9
5 12
0
Sample Output
13 1
failed
Solution
x*n1+y*n2=n,解次一元线性同余方程可以得到所有合法的(x,y)对,找到使得x*c1+y*c2最大的(x,y)即为答案
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 1111
ll extend_gcd(ll a,ll b,ll &x,ll &y)
{ 
    ll d=a;
    if(b)d=extend_gcd(b,a%b,y,x),y-=(a/b)*x;
    else x=1,y=0;
    return d;
}
ll T,n,n1,n2,c1,c2;
bool linear(ll a,ll b,ll c)//求解一元线性同余方程ax=b(mod c)
{
    ll x,y;
    ll g=extend_gcd(a,c,x,y);
    if(b%g)return 0;
    x=x*(b/g);
    int mod=c/g;
    x=(x%mod+mod)%mod;
    y=(b-a*x)/c;
    if(y<0)return 0;
    ll ans=c1*x+c2*y,ansx=x,ansy=y;
    for(int i=1;i<mod;i++)
    {
        x+=mod,y-=a/g;
        if(y<0)break;
        if(c1*x+c2*y<ans)
            ans=c1*x+c2*y,ansx=x,ansy=y;
    }
    printf("%I64d %I64d\n",ansx,ansy);
    return 1;
}
int main()
{
    while(~scanf("%I64d",&n),n)
    {
        scanf("%I64d%I64d%I64d%I64d",&c1,&n1,&c2,&n2);
        if(!linear(n1,n,n2))printf("failed\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值