NOIP2012【国王游戏】

5 篇文章 0 订阅
4 篇文章 0 订阅

【题解】

  一开始看着题觉得是二分答案(最大值的最小值),后来发现不满足单调性

  再后来发现可以用贪心做:只需把大臣按照左手*右手升序排序即可

  证明:

   很显然前面的大臣位置随便调换对后面的大臣并没有影响

  那么假设现在已经排了i-1个大臣,p=a[1]*a[2]*a[3]*……*a[i-1];

  第i个大臣的钱w[i]=p/b[i],第i+1个大臣的钱w[i+1]=p*a[i]/b[i+1]

  若i+1大臣在i大臣前面

  第i个大臣的钱w[i]=p*a[i+1]/b[i],第i+1个大臣的钱w[i+1]=p/b[i+1]

  显然p*a[i+1]/b[i]>p/b[i]  &&  p*a[i]/b[i+1]>p/b[i+1]

  所以两个里面的最大值在p*a[i+1]/b[i] 和 p*a[i]/b[i+1] 之间  

  若p*a[i+1]/b[i] > p*a[i]/b[i+1](这样就是i+1大臣排在i后面最大值会更小) 则 a[i+1]*b[i+1]>a[i]*b[i]

  所以如果要让大臣得到的钱的最大值最小就要保证两个相邻的大臣,前面的左手*右手<后面的左手*右手

  (一年前打的题目,现在写题解还要写好久,果然我还是太菜了)

   详见代码(记得打高精度,还有interesting的高精除法噢233)

   

#include <algorithm> 
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <cstring>
#include <string>
using namespace std;

struct info
  {
    int l,r,k;
  }num[1001];
  
inline bool cmp(const info &a,const info &b)
  {
	return a.k<b.k;
  }
int f[20000];
int i,j,k,l,m,n,t;

int main()
  {
    scanf("%d",&n);
    for(i=0;i<=n;i++)
	  {
        scanf("%d%d",&num[i].l,&num[i].r);
        num[i].k=num[i].r*num[i].l;
      }
    sort(num+1,num+n+1,cmp);
    f[1]=num[0].l;f[0]=1;
    for (int i=1;i<=n-1;i++)
	  {
	   t=0;
    	for (int j=1;j<=f[0];j++)
		  {
    		f[j]*=num[i].l;f[j]+=t; 
			t=f[j]/10000;f[j]%=10000;
    	  }
    	if (t>0) f[++f[0]]=t; 
      }
    t=0;
    for (int i=f[0];i>=1;i--)
	  {
    	t+=f[i];f[i]=t/num[n].r;
    	t%=num[n].r;
    	t*=10000;
      }  
    for (;f[f[0]]==0 && f[0]>0;f[0]--);
    if (f[f[0]]==0) printf("1");else printf("%d",f[f[0]]);
    for (int i=f[0]-1;i>=1;i--)
	  {
    	if (f[i]<10) printf("000");
    	if (f[i]<100 && f[i]>=10) printf("00");
    	if (f[i]<1000 && f[i]>=100) printf("0");
		printf("%d",f[i]);
      }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值