[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;
}
posted @ 2021-12-22 13:57  Coros_Trusds  阅读(50)  评论(0编辑  收藏  举报