问题描述 何老板带领n名游客来到一景区大门口,需要乘坐观光车游览景区。 景区提供两种观光车,一种是每辆车可以坐a名游客,包一辆车费用是p1块钱;另一种每辆车可以坐b名游客,包一辆车费用是p2块钱。 何老板想让这n名游客都坐上观光车,且每辆车都坐满。问何老板至少要花费多少钱? 输入格式 第一行,一个整数n,表示游客的总数。 第二行,两个空格间隔的整数,表示p1和a 第三行,两个空格间隔的整数,表示p2和b 输出格式 一行,一个整数,表示所需最少费用。 如果无解,输出“-1”
样例输入 1 43 1 3 2 4 样例输出 1 15 样例输入 2 40 5 9 5 12 样例输出 2 -1 提示 样例1说明:第一种车13辆,第二种车1辆 1 <= n,a,b,p1,p2 <= 2,000,000,000
分析:
设第一种车、第二种车分别包x,y,辆
x*a+y*b=n;
设 x1,y1 是满足上式的一组解 cost= (x1+t*dx)*p1+(y1-t*dy)*p2 =x1*p1+y1*p2+ (dx*p1-dy*p2)*t;
是一个关于t的一次函数;记斜率为K=dx*p1-dy*p2 由于x,y>0,可以求出t的定义域: x=x1+dx*t>=0 ==> t >= -x1/dx; y=y1-dy*t>=0 ==> t <= y1/dy; 若 K<0 ,t=tmin=-x1/dx; K>=0,t=tmax=y1/dy;
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#define LL long long
using namespace std;
LL n,p1,p2,a,b;
LL extend_gcd(LL a,LL b,LL &x,LL &y ){
LL x0,y0,r;
if(b==0){x=1;y=0; return a;}
r=extend_gcd(b,a%b,x0,y0);
x=y0; y=x0-a/b*y0;
return r;
}
int main(){
LL gcd,x,y,mint,maxt,ans,dx,dy,k,t;
cin>>n>>p1>>a>>p2>>b;
gcd=extend_gcd(a,b,x,y);
if(n%gcd!=0){
cout<<-1; return 0;
}
x= x*n/gcd; y=y*n/gcd;
ans= x*p1+y*p2;
dx= b/gcd; dy= a/gcd;
k= (dx*p1-dy*p2);
maxt= floor(((double) y)/dy);
mint= ceil(((double) x)/ -dx);
if(maxt<mint){
cout<<"-1"; return 0;
}
else if(k>0) t=mint;
else t=maxt;
cout<<ans+k*t<<endl;
//cout<<"k= "<<k<<" dx= "<<dx<<" dy="<<dy<<endl;
//cout<<"x= "<<x<<" y= "<<y<<" mint= "<<mint<<" maxt= "<<maxt<<endl;
}