[BalticOI 2020/2012 Day0] Roses
题目大意
需要买 \(n\) 朵花,现在有两家花店,价格分别是:\(b\) 元每 \(a\) 朵花和 \(d\) 元买 \(c\) 朵花。
给定 \(n,a,b,c,d\),求最小价钱。
题目分析
两家花店单枝花的价格分别为:\(\dfrac{b}{a}\) 元/朵、\(\dfrac{d}{c}\) 元/朵。
设第一家花店的单价比第二家低,则有:\(\dfrac{b}{a}<\dfrac{d}{c}\)。
两边同时 \(\times ac(ac>0)\) 得 \(b\cdot c<d\cdot a\)。
求解部分。
我们枚举在单价较高的花店买花的个数 \(i\),这一家花店为 \(i\times c\),于是另一家花店的就是 \(n-c\times i\)。
答案即为 \(\min\{i\times d+[n-c\times i>0]\times(\dfrac{n-c\times i-1}{a}+1)\times b\}(0\le i\le \dfrac{a}{\gcd(a,c)})\)。
其中 \([....]\) 表示 [
和 ]
之间的逻辑语句是否为真。
注意事项:
-
不开
________
见______
。 -
最开始需保持第一家花店的单价低于第二家,如果不满足,交换即可。
代码
//2021/12/22
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <climits>//need "INT_MAX","INT_MIN"
#include <cstring>//need "memset"
#include <algorithm>
#define int long long
#define enter() putchar(10)
#define debug(c,que) cerr<<#c<<" = "<<c<<que
#define cek(c) puts(c)
#define blow(arr,st,ed,w) for(register int i=(st);i<=(ed);i++)cout<<arr[i]<<w;
#define speed_up() cin.tie(0),cout.tie(0)
#define endl "\n"
#define Input_Int(n,a) for(register int i=1;i<=n;i++)scanf("%d",a+i);
#define Input_Long(n,a) for(register long long i=1;i<=n;i++)scanf("%lld",a+i);
#define mst(a,k) memset(a,k,sizeof(a))
namespace Newstd
{
inline int read()
{
int x=0,k=1;
char ch=getchar();
while(ch<'0' || ch>'9')
{
if(ch=='-')
{
k=-1;
}
ch=getchar();
}
while(ch>='0' && ch<='9')
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*k;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
}
using namespace Newstd;
using namespace std;
const int INF=0x3f3f3f3f3f3f3f;
int n,a,b,c,d;
inline int gcd(int a,int b)
{
if(b==0)
{
return a;
}
return gcd(b,a%b);
}
#undef int
int main(void)
{
#define int long long
n=read(),a=read(),b=read(),c=read(),d=read();
if(a*d<b*c)
{
swap(a,c);
swap(b,d);
}
int ans=INF;
for(register int i=0;i<=a/gcd(a,c);i++)
{
int x=n-c*i,t=i*d;
if(x>0)
{
t+=((x-1)/a+1)*b;
}
ans=min(ans,t);
}
printf("%lld\n",ans);
return 0;
}