sicily 1099. Packing Passengers

#include<iostream>            //线性同余方程   Run Time: 0.15secs
#include<cmath>

#include<stdio.h>
using namespace std;
long long x,y,q;
void extend_eulid(long long a,long long b) //扩展欧几里德定理, x*a+y*b=gcd(a,b)=q
{

if(b==0)
{
x=1;y=0;q=a;
}
else
{
extend_eulid(b,a%b);
long long temp=x;
x=y;y=temp-a/b*y;
}
}
int main()
{
int n,ca,pa,cb,pb,cnt=1;
long long upper,lower,t;
while(cin>>n&&n)
{
cin>>ca>>pa>>cb>>pb;
extend_eulid(pa,pb);
if(n%q!=0)
printf("Data set %d: cannot be flown\n",cnt++);
else
{
x = x*n/q; y = y*n/q; //这里就要用到long long
upper=floor((double)y/(pa/q));

lower=ceil((double)-x/(pb/q));
t=pb*ca-pa*cb<=0?upper:lower;
printf("Data set %d: %lld aircraft A, %lld aircraft B\n",cnt++,x+(pb/q)*t,y-(pa/q)*t);
}
}
return 0;
}



//题意:求x,y 满足 x*pa+y*pb=n 同时使得 x*ca+y*cb的值最小,若有多种可能,则选择最大x值的组合
//分析: x*pa+y*pb=n 可以用 线性同余方程 求得各组解: X=x+(pb/q)*t, Y=y-(pa/q)*t
//t为整数,显然 X,Y>=0,所以 -x/(pb/q) <= t <= y/(pa/q)
//欲使 x*ca+y*cb 最小, 注意到 其中 [(pb/q)*t]*ca + [-(pa/q)*t]*cb = (pb*ca-pa*cb)/q*t
//于是,当pb*ca-pa*cb<0,t应取最大值; 当pb*ca-pa*cb>0,t应取最小值;
//当pb*ca-pa*cb=0,应选择较大的X值,显然 pb/q总是大于0的,所以t 选择最大值,X取得更大值

posted on 2011-07-05 03:24  sysu_mjc  阅读(326)  评论(0编辑  收藏  举报

导航