SDAU数论练习五-F【贪心】

Discription
On one of the Caribbean Islands there are N tourists and you want to move them from this island to another one.

There are only two boats on this island, the first one can hold n1 tourists and cost c1 to move exactly n1 tourists from one Island to another, and the second one can hold n2 and cost c2.

The boat will not sail unless it is fully booked. Moreover, you want to minimize the total cost of moving all tourists from one island to another. You can use any boat several times.

Input
The input may contain multiple test cases. Each test case begins with a line containing an integer N (1 ≤ N ≤ 2 * 109).

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 * 109.

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 non-negative integers m1 and m2, where m1 is the number of times to use the first boat, and m2 is the number of times to use the second boat) if one exists.

Print “failed” otherwise. If a solution exists, you may assume that it is unique.

Examples

Input
43
1 3
2 4
40
5 9
5 12
0

Output
13 1
failed

题意
在一个加勒比岛上,有N个游客,您想将他们从这个岛上移到另一个岛上。
这个岛上只有两艘船,第一个船可以容纳n1名游客,花费c1即可将n1名游客从一个岛准确地移动到另一个岛,第二艘船可以容纳n2名游客,花费c2。
除非船满员,否则它不会航行。此外,您希望最大程度地减少将所有游客从一个岛转移到另一个岛的总成本。您可以多次使用任何一条船。
对于输入中的每个测试用例,打印包含最小成本解决方案的行:两个非负整数m1和m2,其中m1是使用第一条船的次数,m2是使用第二条船的次数船)(如果存在)。
否则,打印“失败”。如果存在解决方案,则可以假定它是唯一的。

思路
比较c1/n1和c2/n2的大小,开始先把所有的人都放在小的船上,看是否能够正好装完,如果不能则减少少的一条船,剩下的人放在比值大的一条船上,如果能够整除则正好,不能再调一船比值小的船人道比值大的上,以此类推。
比值我用最小公倍数通分了。

AC代码

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

ll gcd(ll a,ll b)
{
    return b?gcd(b,a%b):a;
}

ll lcm(ll a,ll b)
{
    return a*b/gcd(a,b);
}

ll n,c1,n1,c2,n2,ans1,ans2;

int main()
{
    while(scanf("%lld",&n)!=EOF)
    {
        if(n==0)
            break;
        scanf("%lld%lld%lld%lld",&c1,&n1,&c2,&n2);
        int f=0;
        ll res=lcm(n1,n2);
        if(c1*res/n1>=c2*res/n2)
        {
            ll tmp=n/n2;
            for(int i=tmp; i>=0; i--)
            {
                if((n-i*n2)%n1==0)
                {
                    f=1;
                    ans1=(n-i*n2)/n1;
                    ans2=i;
                    printf("%lld %lld\n",ans1,ans2);
                    break;
                }
            }
        //cout<<"&&&"<<endl;
        }
        else
        {
            ll tmp=n/n1;
            for(int i=tmp; i>=0; i--)
            {
                if((n-i*n1)%n2==0)
                {
                    f=1;
                    ans1=i;
                    ans2=(n-i*n1)/n2;
                    printf("%lld %lld\n",ans1,ans2);
                    break;
                }
            }
            //cout<<"%%%"<<endl;
        }
        if(f==0)
            printf("failed\n");
    }
    return 0;
}
发布了306 篇原创文章 · 获赞 105 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43460224/article/details/104125256