【Ybtoj 第2章 例题4】国王游戏【贪心】

在这里插入图片描述
在这里插入图片描述


解题思路
我们对于国王身后的两个点来分析:

  • 队列可能是这样的:
    在这里插入图片描述
    那么我们计算可得 a n s 1 = m a x ( a 0 / b 1 , a 0 ∗ a 1 / b 2 ) ; ans_1=max(a_0/b_1,a_0*a_1/b_2); ans1=max(a0/b1a0a1/b2);

  • 队列也有可能是这样的:
    在这里插入图片描述
    那么我们计算可得 a n s 2 = m a x ( a 0 / b 2 , a 0 ∗ a 2 / b 1 ) ; ans_2=max(a_0/b_2,a_0*a_2/b_1); ans2=max(a0/b2a0a2/b1);

我们来对比一下两个答案:
a n s 1 = m a x ( a 0 / b 1 , a 0 ∗ a 1 / b 2 ) ; ans_1=max(a_0/b_1,a_0*a_1/b_2); ans1=max(a0/b1a0a1/b2);
a n s 2 = m a x ( a 0 / b 2 , a 0 ∗ a 2 / b 1 ) ; ans_2=max(a_0/b_2,a_0*a_2/b_1); ans2=max(a0/b2a0a2/b1);

显然我们可以得到: a 0 ∗ a 1 / b 2 > a 0 / b 2 , a 0 ∗ a 2 / b 1 > a 0 / b 1 a_0*a_1/b_2>a_0/b_2,a_0*a_2/b_1>a_0/b_1 a0a1/b2>a0/b2a0a2/b1>a0/b1
如果 a n s 1 < a n s 2 ans_1 <ans_2 ans1<ans2,那么易得: a 0 ∗ a 1 / b 2 < a 0 ∗ a 2 / b 1 a_0*a_1/b_2<a_0*a_2/b_1 a0a1/b2<a0a2/b1

​变形可得: a 1 ∗ b 1 < a 2 ∗ b 2 a_1*b_1<a_2*b_2 a1b1<a2b2

a 1 ∗ b 1 < a 2 ∗ b 2 a_1*b_1<a_2*b_2 a1b1<a2b2时,我们也能够得到 a n s 1 < a n s 2 ans_1<ans_2 ans1<ans2的结论。所以,为了 a n s ans ans取到最小值,我们需要将 a i ∗ b i a_i*b_i aibi较小的放在前面…

那么我们以 a i ∗ b i a_i*b_i aibi为关键字排序即可,同时,统计答案时一定不要忘了写高精度!


代码

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

int n,cnt,cnt1,cntt,ans[20000],lyx[20000],kj[20000];

struct c{
    
    
	long long x,y;
}a[2000]; 

bool cmp(const c&a,const c&b)
{
    
    
	return a.x*a.y<b.x*b.y;
}

void mul(long long x){
    
    
	int s=0,g=0;
	for(int i=1;i<=cnt;i++)
	{
    
    
		s=ans[i]*x+g;
		ans[i]=s%10;
		g=s/10;
	}
	while(g!=0)
	{
    
    
		ans[++cnt]=g%10;
		g=g/10;
	}
		
}

void cut(long long x){
    
    
	int s=0;
	memset(lyx,0,sizeof(lyx));
	for(int i=cnt;i>0;i--)
	{
    
    
		s=s*10+ans[i];
		if(s>=x)
		{
    
    
			lyx[i]=s/x;
			s=s%x;
		}
	}
	cnt1=cnt;
	while(lyx[cnt1]==0)
	{
    
    
		if(cnt1 == 1)
			break;
		cnt1--;
	}
}

void maxn(){
    
    
	int flag=1;
	if(cnt1>cntt)
	{
    
    
		for(int i=1;i<=cnt1;i++)
			kj[i]=lyx[i];
		cntt=cnt1;	
	}
	else
	{
    
    
		for(int i=cnt1;i>0;i--)
			if(lyx[i]>kj[i])
			{
    
    
				flag=0;
				break;
			}
		if(flag==0)
		{
    
    
			for(int i=1;i<=cnt1;i++)
			kj[i]=lyx[i];
		}
	}
}

int main(){
    
    
	scanf("%d",&n);
	scanf("%lld%lld",&a[0].x,&a[0].y);	
	for(int i=1;i<=n;i++)
		scanf("%lld%lld",&a[i].x,&a[i].y);	
	sort(a+1,a+n+1,cmp);
	ans[1]=1,cnt=1,cnt1=1,cntt=1;
	for(int i=1;i<=n;i++)
	{
    
    
		mul(a[i-1].x);
		cut(a[i].y);
		maxn();
	}
	for(int i=cntt;i>0;i--)
		printf("%d",kj[i]);
}

猜你喜欢

转载自blog.csdn.net/kejin2019/article/details/111722255